diff --git a/eval/eval.py b/eval/eval.py index 53571dd0..7ced20f0 100644 --- a/eval/eval.py +++ b/eval/eval.py @@ -5,7 +5,7 @@ import os import re import time from datetime import datetime -from typing import Any, Dict, List +from typing import Any from openai import AsyncOpenAI from tqdm.asyncio import tqdm_asyncio @@ -44,7 +44,7 @@ class AsyncOpenRouterEvaluator: match = re.search(r"(.*?)", response, re.DOTALL) return match.group(1).strip() if match else response - async def process_single_question(self, entry: Dict, dataset) -> Dict: + async def process_single_question(self, entry: dict, dataset) -> dict: """Process a single question and return the result.""" response = await self.get_model_response(entry["question"]) answer = self.parse_model_response(response) @@ -58,7 +58,7 @@ class AsyncOpenRouterEvaluator: "metadata": entry["metadata"], } - async def evaluate_dataset(self, dataset_config: Dict[str, Any]) -> Dict[str, Any]: + async def evaluate_dataset(self, dataset_config: dict[str, Any]) -> dict[str, Any]: """Evaluate a single dataset with concurrent question processing.""" dataset_name = dataset_config.pop("name") print(f"\nEvaluating dataset: {dataset_name}") @@ -92,7 +92,7 @@ class AsyncOpenRouterEvaluator: print(f"Error evaluating dataset {dataset_name}: {str(e)}") return None - async def evaluate_datasets(self, dataset_configs: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + async def evaluate_datasets(self, dataset_configs: list[dict[str, Any]]) -> list[dict[str, Any]]: """Evaluate multiple datasets concurrently.""" tasks = [self.evaluate_dataset(config) for config in dataset_configs] diff --git a/eval/r1/eval.py b/eval/r1/eval.py index 3dbc39b1..6f7a4a73 100644 --- a/eval/r1/eval.py +++ b/eval/r1/eval.py @@ -5,7 +5,7 @@ import logging import os from dataclasses import asdict from datetime import datetime -from typing import Any, Dict, List +from typing import Any import aiohttp from eval_config import EvalConfig @@ -32,7 +32,7 @@ class OpenRouterEvaluator: } self.semaphore = asyncio.Semaphore(10) # Control concurrency - def save_results(self, results: List[Dict[str, Any]], dataset, dataset_name) -> Dict[str, Any]: + def save_results(self, results: list[dict[str, Any]], dataset, dataset_name) -> dict[str, Any]: file_name = f"{self.output_dir}/{dataset_name}.json" total_score = sum(r["score"] for r in results) @@ -52,7 +52,7 @@ class OpenRouterEvaluator: json.dump(metrics, f, indent=2) return metrics - def prepare_messages(self, prompt: str) -> List[Dict[str, str]]: + def prepare_messages(self, prompt: str) -> list[dict[str, str]]: return { "model": self.model, "messages": [ @@ -92,7 +92,7 @@ class OpenRouterEvaluator: raise Exception("Failed to get valid response after retries") - async def process_entry(self, session: aiohttp.ClientSession, dataset: Any, entry: Any) -> Dict[str, Any]: + async def process_entry(self, session: aiohttp.ClientSession, dataset: Any, entry: Any) -> dict[str, Any]: """Process a single entry with concurrency control.""" async with self.semaphore: response = await self.get_model_response(session, entry["question"]) @@ -108,7 +108,7 @@ class OpenRouterEvaluator: "metadata": str(entry["metadata"]), } - async def evaluate_dataset(self, session: aiohttp.ClientSession, dataset_name: str) -> Dict[str, Any]: + async def evaluate_dataset(self, session: aiohttp.ClientSession, dataset_name: str) -> dict[str, Any]: """Evaluate a single dataset asynchronously.""" self.logger.info(f"\nEvaluating dataset: {dataset_name}") dataset = reasoning_gym.create_dataset( @@ -119,7 +119,7 @@ class OpenRouterEvaluator: results = await asyncio.gather(*tasks) return self.save_results(results, dataset, dataset_name) - async def evaluate_datasets(self) -> List[Dict[str, Any]]: + async def evaluate_datasets(self) -> list[dict[str, Any]]: """Main async evaluation entry point.""" all_results = [] async with aiohttp.ClientSession(headers=self.headers) as session: diff --git a/eval/r1/eval_config.py b/eval/r1/eval_config.py index 9a6c96f6..80b76dd4 100644 --- a/eval/r1/eval_config.py +++ b/eval/r1/eval_config.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import List, Union +from typing import Union import yaml @@ -9,7 +9,7 @@ from reasoning_gym.utils import SYSTEM_PROMPTS @dataclass class EvalConfig: category: str - datasets: Union[str, List[str]] + datasets: Union[str, list[str]] eval_dir: str dataset_size: int dataset_seed: int diff --git a/examples/OpenRLHF/custom_reward.py b/examples/OpenRLHF/custom_reward.py index 638cdc97..899aa044 100644 --- a/examples/OpenRLHF/custom_reward.py +++ b/examples/OpenRLHF/custom_reward.py @@ -6,7 +6,7 @@ import math import os from dataclasses import dataclass from datetime import datetime -from typing import Any, List, Optional, Tuple +from typing import Any, Optional import torch import torch.nn as nn @@ -109,7 +109,7 @@ class AlgorithmicRewardExperienceMaker(NaiveExperienceMaker): self.dataset = dataset @torch.no_grad() - def generate_samples(self, all_prompts: List[Tuple[str, Any]], **generate_kwargs) -> List[Samples]: + def generate_samples(self, all_prompts: list[tuple[str, Any]], **generate_kwargs) -> list[Samples]: """ Generate samples and return in batches. """ diff --git a/examples/veRL/main_ppo_custom_reward_server.py b/examples/veRL/main_ppo_custom_reward_server.py index 0f20be1d..4a0eccc0 100644 --- a/examples/veRL/main_ppo_custom_reward_server.py +++ b/examples/veRL/main_ppo_custom_reward_server.py @@ -1,7 +1,7 @@ # This example is an adapted version of Bytedance's code: # https://github.com/volcengine/verl/blob/a65c9157bc0b85b64cd753de19f94e80a11bd871/verl/trainer/main_ppo.py import os -from typing import Dict, List, Optional +from typing import Optional import hydra import ray @@ -64,12 +64,12 @@ class ReasoningGymDataset(Dataset): self.client.create_experiment(dataset_name, config) # Cache for batches - self._batch_cache: dict[int, List[BatchEntry]] = {} + self._batch_cache: dict[int, list[BatchEntry]] = {} def __len__(self) -> int: return self.size - def _get_batch(self, batch_idx: int) -> List[BatchEntry]: + def _get_batch(self, batch_idx: int) -> list[BatchEntry]: """Fetch or retrieve cached batch""" if batch_idx not in self._batch_cache: base_index = batch_idx * self.batch_size diff --git a/examples/word_ladder/main.py b/examples/word_ladder/main.py index 4cbd88c9..1157c093 100644 --- a/examples/word_ladder/main.py +++ b/examples/word_ladder/main.py @@ -14,7 +14,7 @@ from typing import Any, Dict from examples.word_ladder.utils import create_word_ladders, generate_reasoning -def create_dataset(jsonl_path: Path, config: Dict[str, Any]) -> bool: +def create_dataset(jsonl_path: Path, config: dict[str, Any]) -> bool: """ Creates the word ladder dataset, handling potential exhaustion gracefully. diff --git a/notebooks/gsm-symbolic-cot.txt b/notebooks/gsm-symbolic-cot.txt index 3ebc054d..1d0ca4b2 100644 --- a/notebooks/gsm-symbolic-cot.txt +++ b/notebooks/gsm-symbolic-cot.txt @@ -15,7 +15,7 @@ OUTPUT 1: Output in the form which should be generated from random import Random from typing import Dict, Any -def generate_from_variables(time_per_interval: int, distance_per_interval: int, total_distance: int) -> Dict[str, Any]: +def generate_from_variables(time_per_interval: int, distance_per_interval: int, total_distance: int) -> dict[str, Any]: intervals = total_distance // distance_per_interval total_time = intervals * time_per_interval @@ -36,7 +36,7 @@ def generate_from_variables(time_per_interval: int, distance_per_interval: int, }} }} -def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: # Generate random values scaled by difficulty distance_per_interval = int(rng.randint(2, int(10 * difficulty))) time_per_interval = int(rng.randint(5, int(30 * difficulty))) @@ -57,7 +57,7 @@ def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }} }} -def original_example() -> Dict[str, Any]: +def original_example() -> dict[str, Any]: return generate_from_variables(10, 3, 42) ``` @@ -79,7 +79,7 @@ from random import Random from typing import Dict, Any def generate_from_variables(name: str, food: str, rate_per_min: int, batch_size: int, - time_per_batch: int, total_amount: int) -> Dict[str, Any]: + time_per_batch: int, total_amount: int) -> dict[str, Any]: peel_time = total_amount // rate_per_min num_batches = total_amount // batch_size cook_time = num_batches * time_per_batch @@ -110,7 +110,7 @@ def generate_from_variables(name: str, food: str, rate_per_min: int, batch_size: } } -def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Emily", "Sarah", "Emma", "Sophia", "Olivia", "Ava", "Isabella", "Mia"] foods = ["shrimp", "onion", "carrot", "mushroom", "clam"] @@ -139,7 +139,7 @@ def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: } } -def original_example() -> Dict[str, Any]: +def original_example() -> dict[str, Any]: return generate_from_variables("Emily", "shrimp", 6, 30, 10, 90) ``` @@ -161,7 +161,7 @@ from random import Random from typing import Dict, Any def generate_from_variables(family: str, item: str, total: int, n1: int, n2: int, - flavor1: str, flavor2: str, flavor3: str) -> Dict[str, Any]: + flavor1: str, flavor2: str, flavor3: str) -> dict[str, Any]: n3 = total - (n1 + n2) question = f"The {family} family is busy making {item}s. So far, they've made {total} {item}s. They have {n1} {flavor1} {item}s, {n2} {flavor2} {item}s, and some {flavor3} {item}s. How many {flavor3} {item}s have they made?" @@ -186,7 +186,7 @@ def generate_from_variables(family: str, item: str, total: int, n1: int, n2: int } } -def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: families = ["Smith", "Johnson", "Williams", "Brown", "Jones"] items = ["cupcake", "muffin", "brownie", "biscuit"] flavors = ["vanilla", "strawberry", "blueberry", "lemon", "peanut butter"] @@ -217,7 +217,7 @@ def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: } } -def original_example() -> Dict[str, Any]: +def original_example() -> dict[str, Any]: return generate_from_variables("Adams", "cookie", 7995, 2595, 3075, "rainbow", "oatmeal", "chocolate chip") ``` @@ -241,7 +241,7 @@ from typing import Dict, Any def generate_from_variables(name: str, event: str, food: str, obj: str, package_husband: int, used_spoons: int, - remaining_spoons: int) -> Dict[str, Any]: + remaining_spoons: int) -> dict[str, Any]: total_spoons = remaining_spoons + used_spoons package_julia = total_spoons - package_husband @@ -268,7 +268,7 @@ def generate_from_variables(name: str, event: str, food: str, obj: str, } } -def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ['Emma', 'Olivia', 'Ava', 'Isabella', 'Sophia', 'Mia', 'Charlotte'] events = ['lunch party', 'birthday party', 'potluck party', 'baby shower', 'game night'] foods = ['roast chicken', 'grilled salmon', 'beef stew', 'vegetable lasagna', @@ -298,7 +298,7 @@ def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: } } -def original_example() -> Dict[str, Any]: +def original_example() -> dict[str, Any]: return generate_from_variables('Julia', 'dinner party', 'stew', 'spoons', 5, 3, 12) ``` diff --git a/reasoning_gym/algebra/complex_arithmetic.py b/reasoning_gym/algebra/complex_arithmetic.py index c55e1d09..5f97b9ee 100644 --- a/reasoning_gym/algebra/complex_arithmetic.py +++ b/reasoning_gym/algebra/complex_arithmetic.py @@ -2,7 +2,7 @@ import cmath import math import random from dataclasses import dataclass -from typing import Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -13,7 +13,7 @@ class ComplexArithmeticConfig: max_real: int = 10 min_imag: int = -10 max_imag: int = 10 - operations: Tuple[str, ...] = ("+", "-", "*", "/") + operations: tuple[str, ...] = ("+", "-", "*", "/") seed: Optional[int] = None size: int = 500 diff --git a/reasoning_gym/algebra/intermediate_integration.py b/reasoning_gym/algebra/intermediate_integration.py index 84e01d9b..b4fb28ea 100644 --- a/reasoning_gym/algebra/intermediate_integration.py +++ b/reasoning_gym/algebra/intermediate_integration.py @@ -241,7 +241,7 @@ In addition, when doing calculation, use the following instructions together wit }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the problem""" reward = 0.0 metadata = entry["metadata"] diff --git a/reasoning_gym/algebra/polynomial_equations.py b/reasoning_gym/algebra/polynomial_equations.py index cd4842ee..c069c32f 100644 --- a/reasoning_gym/algebra/polynomial_equations.py +++ b/reasoning_gym/algebra/polynomial_equations.py @@ -1,8 +1,7 @@ import math import random -import string from dataclasses import dataclass -from typing import Dict, List, Optional, Tuple +from typing import Any, Optional from sympy import Eq, Symbol, expand, solve @@ -21,7 +20,7 @@ class PolynomialEquationsConfig: max_value: int = 100 # Maximum value for coefficients min_degree: int = 1 # Minimum polynomial degree max_degree: int = 3 # Maximum polynomial degree - operators: Tuple[str, ...] = ( + operators: tuple[str, ...] = ( "+", "-", ) # Allowed operators between terms, Avoid adding '*' or '/' because they will affect the degree @@ -163,7 +162,7 @@ In solving the equations, please abide by the following instruction: return polynomial_expr - def _parse_score_to_list(self, answer: Optional[str]) -> List[float]: + def _parse_score_to_list(self, answer: Optional[str]) -> list[float]: """Parses a comma-separated string of scores into a sorted list of floats. This method takes a string containing comma-separated numeric values, @@ -193,7 +192,7 @@ In solving the equations, please abide by the following instruction: return sorted(output_float_vals) # Return the sorted list of floats - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """ Score an answer based on its numerical distance to oracle solutions using exponential decay. This function compares a predicted answer (or list of answers) to a set of oracle solutions diff --git a/reasoning_gym/algebra/polynomial_multiplication.py b/reasoning_gym/algebra/polynomial_multiplication.py index 8617db17..09e2530a 100644 --- a/reasoning_gym/algebra/polynomial_multiplication.py +++ b/reasoning_gym/algebra/polynomial_multiplication.py @@ -1,7 +1,6 @@ import random -import warnings from dataclasses import dataclass -from typing import Any, Dict, Optional, Tuple +from typing import Any, Optional import sympy as sp from sympy.polys.monomials import itermonomials @@ -23,10 +22,10 @@ class PolynomialMultiplicationConfig: max_degree: int = 3 # Maximum polynomial degree min_polynomials: int = 2 # Minimum number of polynomials being multiplied max_polynomials: int = 3 # Maximum number of polynomials being multiplied - variables: Tuple[str] = ("x", "y", "z") # Tuple of variable names, that will be chosen randomly + variables: tuple[str] = ("x", "y", "z") # Tuple of variable names, that will be chosen randomly allow_cross_variable_product: bool = False # Generate tasks like "Multiply (x^2+3x-1)*(y^2-5)" allow_multivariate_polynomials: bool = False # Generate multivariate tasks like "Multiply (2x^2 + 3y)*(5x^2+3x-1)" - operators: Tuple[str, ...] = ( + operators: tuple[str, ...] = ( "+", "-", ) # Allowed operators between terms, Avoid adding '*' or '/' because they will affect the degree @@ -146,7 +145,7 @@ In addition, When doing calculation, Use the following instructions together wit return polynomial_expr - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: reward = 0.0 metadata = entry["metadata"] if answer is not None: diff --git a/reasoning_gym/algebra/simple_equations.py b/reasoning_gym/algebra/simple_equations.py index c8de94b8..778f51a9 100644 --- a/reasoning_gym/algebra/simple_equations.py +++ b/reasoning_gym/algebra/simple_equations.py @@ -1,7 +1,7 @@ import random import string from dataclasses import dataclass -from typing import Optional, Tuple +from typing import Optional from sympy import Symbol @@ -69,7 +69,7 @@ class SimpleEquationsDataset(ProceduralDataset): """Get a random lowercase variable name""" return rng.choice(string.ascii_lowercase) - def _generate_equation(self, rng: random.Random, variable: str) -> Tuple[str, int]: + def _generate_equation(self, rng: random.Random, variable: str) -> tuple[str, int]: """Generate an equation and its solution Args: diff --git a/reasoning_gym/algebra/simple_integration.py b/reasoning_gym/algebra/simple_integration.py index 8dfa775b..019cdf90 100644 --- a/reasoning_gym/algebra/simple_integration.py +++ b/reasoning_gym/algebra/simple_integration.py @@ -86,7 +86,7 @@ In addition, When doing calculation, Use the following instructions together wit }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the problem""" reward = 0.0 metadata = entry["metadata"] diff --git a/reasoning_gym/algorithmic/ab.py b/reasoning_gym/algorithmic/ab.py index 1daea0e9..139e4af8 100644 --- a/reasoning_gym/algorithmic/ab.py +++ b/reasoning_gym/algorithmic/ab.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -129,14 +129,14 @@ Return the final state of the program. "metadata": {}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the AB task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/base_conversion.py b/reasoning_gym/algorithmic/base_conversion.py index 48c7ecbf..bd897a89 100644 --- a/reasoning_gym/algorithmic/base_conversion.py +++ b/reasoning_gym/algorithmic/base_conversion.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from random import Random -from typing import Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -61,7 +61,7 @@ class BaseConversionDataset(ProceduralDataset): else: return f"base-{base}" - def _generate_conversion(self, rng: Random) -> Tuple[int, int, int]: + def _generate_conversion(self, rng: Random) -> tuple[int, int, int]: """Generate random value and source/target bases""" value = rng.randint(self.config.min_value, self.config.max_value) diff --git a/reasoning_gym/algorithmic/binary_matrix.py b/reasoning_gym/algorithmic/binary_matrix.py index 509b8042..92317e78 100644 --- a/reasoning_gym/algorithmic/binary_matrix.py +++ b/reasoning_gym/algorithmic/binary_matrix.py @@ -7,7 +7,7 @@ https://leetcode.com/problems/01-matrix/description/ from collections import deque from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -112,7 +112,7 @@ class BinaryMatrixDataset(ProceduralDataset): """Get a string representation of the matrix""" return "\n".join(" ".join(str(x) for x in row) for row in matrix) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["answer"] if answer is not None: diff --git a/reasoning_gym/algorithmic/cryptarithm.py b/reasoning_gym/algorithmic/cryptarithm.py index 52c492d1..e04516a1 100644 --- a/reasoning_gym/algorithmic/cryptarithm.py +++ b/reasoning_gym/algorithmic/cryptarithm.py @@ -211,14 +211,14 @@ class CryptarithmDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the Cryptarithm task. The function awards 1.0 for a correct format and answers for all alphabet pairs. Args: answer (Optional[str]): The user's answer already parsed by `extract_answer` - answer_str (Dict[str, any]): The original dataset answer_str containing the correct answer. ie "A=1,B=3..." + answer_str (dict[str, Any]): The original dataset answer_str containing the correct answer. ie "A=1,B=3..." Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/game_of_life.py b/reasoning_gym/algorithmic/game_of_life.py index b4ac1855..7a1647e7 100644 --- a/reasoning_gym/algorithmic/game_of_life.py +++ b/reasoning_gym/algorithmic/game_of_life.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional import cellpylib as cpl @@ -86,14 +86,14 @@ class GameOfLifeDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the GoL task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/graph_color.py b/reasoning_gym/algorithmic/graph_color.py index 8f730b25..3e1287b5 100644 --- a/reasoning_gym/algorithmic/graph_color.py +++ b/reasoning_gym/algorithmic/graph_color.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -209,14 +209,14 @@ Return your solution as a JSON map of vertices to colors. (For example: {{0: 1, "metadata": {"possible_answer": solution, "puzzle": puzzle}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the GraphColor task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/group_anagrams.py b/reasoning_gym/algorithmic/group_anagrams.py index e3f65013..caf46357 100644 --- a/reasoning_gym/algorithmic/group_anagrams.py +++ b/reasoning_gym/algorithmic/group_anagrams.py @@ -10,7 +10,7 @@ import json from collections import defaultdict from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..data import get_data_file_path from ..factory import ProceduralDataset, register_dataset @@ -88,7 +88,7 @@ class GroupAnagramsDataset(ProceduralDataset): anagrams = list(res.values()) return self._sort_nested_list(anagrams) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Score a single Group Anagrams question""" reward = 0.0 if answer is not None: diff --git a/reasoning_gym/algorithmic/letter_jumble.py b/reasoning_gym/algorithmic/letter_jumble.py index b659f6d5..86cce2b3 100644 --- a/reasoning_gym/algorithmic/letter_jumble.py +++ b/reasoning_gym/algorithmic/letter_jumble.py @@ -3,7 +3,7 @@ import re from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from reasoning_gym.data import read_data_file @@ -123,14 +123,14 @@ class LetterJumbleDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves this task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/number_filtering.py b/reasoning_gym/algorithmic/number_filtering.py index 64d8bc02..f122f04c 100644 --- a/reasoning_gym/algorithmic/number_filtering.py +++ b/reasoning_gym/algorithmic/number_filtering.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from random import Random -from typing import List, Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -39,7 +39,7 @@ class NumberFilteringDataset(ProceduralDataset): """Format a number with specified decimal places""" return f"{num:.{decimals}f}" - def _generate_numbers(self, rng: Random) -> Tuple[List[float], List[str]]: + def _generate_numbers(self, rng: Random) -> tuple[list[float], list[str]]: """Generate list of numbers and their string representations""" count = rng.randint(self.config.min_numbers, self.config.max_numbers) numbers = [] diff --git a/reasoning_gym/algorithmic/number_sorting.py b/reasoning_gym/algorithmic/number_sorting.py index f906d230..c7170347 100644 --- a/reasoning_gym/algorithmic/number_sorting.py +++ b/reasoning_gym/algorithmic/number_sorting.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from random import Random -from typing import List, Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -46,7 +46,7 @@ Please follow the instruction below: # Reparse to ensure exact decimal representation return f"{float(formatted):.{decimals}f}" - def _generate_numbers(self, rng: Random) -> Tuple[List[float], List[str]]: + def _generate_numbers(self, rng: Random) -> tuple[list[float], list[str]]: """Generate list of numbers and their string representations""" count = rng.randint(self.config.min_numbers, self.config.max_numbers) decimals = rng.randint(self.config.min_decimals, self.config.max_decimals) diff --git a/reasoning_gym/algorithmic/palindrome_generation.py b/reasoning_gym/algorithmic/palindrome_generation.py index ce2db322..2eca2693 100644 --- a/reasoning_gym/algorithmic/palindrome_generation.py +++ b/reasoning_gym/algorithmic/palindrome_generation.py @@ -90,7 +90,7 @@ class PalindromeDataset(ProceduralDataset): """Return the palindrome string from the letter set.""" return "".join(letters) - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided is a valid palindrome. The answer is expected to be a single string diff --git a/reasoning_gym/algorithmic/palindrome_partitioning.py b/reasoning_gym/algorithmic/palindrome_partitioning.py index 6a2dbe60..e0d41870 100644 --- a/reasoning_gym/algorithmic/palindrome_partitioning.py +++ b/reasoning_gym/algorithmic/palindrome_partitioning.py @@ -8,7 +8,7 @@ import json import string from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -93,7 +93,7 @@ class PalindromePartitioningDataset(ProceduralDataset): _partition(0) return self._sort_list(res) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Score a single Palindrome Partitioning question""" if answer is not None: try: diff --git a/reasoning_gym/algorithmic/pool_matrix.py b/reasoning_gym/algorithmic/pool_matrix.py index dda7ed2d..4d14c9cf 100644 --- a/reasoning_gym/algorithmic/pool_matrix.py +++ b/reasoning_gym/algorithmic/pool_matrix.py @@ -1,9 +1,8 @@ """Perform average / max pooling on a matrix""" -from copy import deepcopy from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional import numpy as np @@ -95,7 +94,7 @@ class PoolMatrixDataset(ProceduralDataset): ] ) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Score the answer based on the metadata""" reward = 0.0 diff --git a/reasoning_gym/algorithmic/ransom_note.py b/reasoning_gym/algorithmic/ransom_note.py index 633cb62c..2a1826a0 100644 --- a/reasoning_gym/algorithmic/ransom_note.py +++ b/reasoning_gym/algorithmic/ransom_note.py @@ -7,7 +7,7 @@ https://leetcode.com/problems/ransom-note/description/ from collections import defaultdict from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -95,14 +95,14 @@ class RansomNoteDataset(ProceduralDataset): "metadata": {"ransom_note": ransom_note, "magazine": magazine, "solution": answer, "solvable": solvable}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves this task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/algorithmic/sentence_reordering.py b/reasoning_gym/algorithmic/sentence_reordering.py index f1303f09..b96fe8a4 100644 --- a/reasoning_gym/algorithmic/sentence_reordering.py +++ b/reasoning_gym/algorithmic/sentence_reordering.py @@ -92,7 +92,7 @@ class SentenceReorderingDataset(ProceduralDataset): "metadata": {"word_count": word_count}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: reward = 0.0 expected_answer = entry["answer"] if answer is not None: diff --git a/reasoning_gym/algorithmic/spell_backward.py b/reasoning_gym/algorithmic/spell_backward.py index 60af94b6..9a978372 100644 --- a/reasoning_gym/algorithmic/spell_backward.py +++ b/reasoning_gym/algorithmic/spell_backward.py @@ -49,7 +49,7 @@ class SpellBackwardDataset(ProceduralDataset): "metadata": {"word": word, "word_len": len(word)}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: reward = 0.0 expected_answer = entry["answer"] if answer is not None: diff --git a/reasoning_gym/algorithmic/spiral_matrix.py b/reasoning_gym/algorithmic/spiral_matrix.py index fe65cc87..17aff844 100644 --- a/reasoning_gym/algorithmic/spiral_matrix.py +++ b/reasoning_gym/algorithmic/spiral_matrix.py @@ -6,7 +6,7 @@ https://leetcode.com/problems/spiral-matrix/description/ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -116,7 +116,7 @@ class SpiralMatrixDataset(ProceduralDataset): "metadata": {"matrix": matrix, "solution": answer}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["answer"].strip() diff --git a/reasoning_gym/algorithmic/string_insertion.py b/reasoning_gym/algorithmic/string_insertion.py index 77ea075f..d09b8a92 100644 --- a/reasoning_gym/algorithmic/string_insertion.py +++ b/reasoning_gym/algorithmic/string_insertion.py @@ -5,7 +5,7 @@ https://github.com/yongchao98/CodeSteer-v1.0/blob/main/create_dataset/create_dat from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -80,7 +80,7 @@ class StringInsertionDataset(ProceduralDataset): i += 1 return "".join(output) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["answer"] if answer is not None: diff --git a/reasoning_gym/algorithmic/word_ladder.py b/reasoning_gym/algorithmic/word_ladder.py index 928a4c97..18670d4b 100644 --- a/reasoning_gym/algorithmic/word_ladder.py +++ b/reasoning_gym/algorithmic/word_ladder.py @@ -3,7 +3,7 @@ from collections import deque from dataclasses import dataclass from random import Random -from typing import Dict, List, Optional, Set, Tuple +from typing import Any, Optional from ..data import get_data_file_path from ..factory import ProceduralDataset, register_dataset @@ -82,7 +82,7 @@ class WordLadderDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) @classmethod - def _load_words_from_csv(cls, min_length: int = 3, max_length: int = 5) -> Dict[int, Set[str]]: + def _load_words_from_csv(cls, min_length: int = 3, max_length: int = 5) -> dict[int, set[str]]: """Load words from CSV file organized by length""" # Validate length range before processing assert 3 <= min_length <= max_length <= 5, "Word length must be between 3 and 5 inclusive" @@ -117,7 +117,7 @@ class WordLadderDataset(ProceduralDataset): return word_sets - def _get_neighbors(self, word: str, word_set: Set[str]) -> Set[str]: + def _get_neighbors(self, word: str, word_set: set[str]) -> set[str]: """Get neighbors from either precomputed graph or by computing on demand""" # Try precomputed graph first if len(word) in self.word_graphs and word in self.word_graphs[len(word)]: @@ -132,7 +132,7 @@ class WordLadderDataset(ProceduralDataset): neighbors.add(neighbor) return neighbors - def _build_word_graph(self, word_length: int) -> Dict[str, Set[str]]: + def _build_word_graph(self, word_length: int) -> dict[str, set[str]]: """Build graph of word connections for given length, using caching""" # Return cached graph if it exists if word_length in self.word_graphs: @@ -156,7 +156,7 @@ class WordLadderDataset(ProceduralDataset): self.word_graphs[word_length] = graph return self.word_graphs[word_length] - def _find_path(self, start: str, end: str, word_set: Set[str]) -> Optional[List[str]]: + def _find_path(self, start: str, end: str, word_set: set[str]) -> Optional[list[str]]: """Simplified path finding using BFS for shortest paths""" # Early exit if words are direct neighbors if end in self._get_neighbors(start, word_set): @@ -181,7 +181,7 @@ class WordLadderDataset(ProceduralDataset): return None - def _generate_word_pair(self, rng: Random, length: int) -> Tuple[str, str, List[str]]: + def _generate_word_pair(self, rng: Random, length: int) -> tuple[str, str, list[str]]: """Simplified word pair generation""" word_set = self.word_sets[length] words_list = sorted(word_set) @@ -220,7 +220,7 @@ class WordLadderDataset(ProceduralDataset): "metadata": {"start_word": start, "end_word": end, "word_length": length, "chain_length": len(path)}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: if answer is None: return 0 diff --git a/reasoning_gym/algorithmic/word_sorting.py b/reasoning_gym/algorithmic/word_sorting.py index 34951c0c..61c8b61d 100644 --- a/reasoning_gym/algorithmic/word_sorting.py +++ b/reasoning_gym/algorithmic/word_sorting.py @@ -4,7 +4,7 @@ import re from dataclasses import dataclass from enum import StrEnum from random import Random -from typing import Dict, List, Optional, Tuple +from typing import Any, Optional from ..data import read_data_file from ..factory import ProceduralDataset, register_dataset @@ -84,7 +84,7 @@ class WordSortingDataset(ProceduralDataset): return "".join(c.upper() if rng.choice([True, False]) else c.lower() for c in word) return word # ORIGINAL case - def _generate_words(self, rng: Random) -> Tuple[List[str], List[str]]: + def _generate_words(self, rng: Random) -> tuple[list[str], list[str]]: """Generate list of words and their transformed versions""" count = rng.randint(self.config.min_words, self.config.max_words) @@ -122,7 +122,7 @@ class WordSortingDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: oracle_answer = entry["metadata"]["sorted_words"] if answer is not None and len(answer) > 0: parsed_answer = [word.strip() for word in re.split(r",\s*", answer)] diff --git a/reasoning_gym/arc/arc_1d_tasks.py b/reasoning_gym/arc/arc_1d_tasks.py index 61151b34..d74d75ed 100644 --- a/reasoning_gym/arc/arc_1d_tasks.py +++ b/reasoning_gym/arc/arc_1d_tasks.py @@ -1,13 +1,13 @@ from random import Random -from typing import Dict, List, Optional +from typing import Optional -def gen_field(size: int, color: int = 0) -> List[int]: +def gen_field(size: int, color: int = 0) -> list[int]: """Generate a field of given size filled with specified color (default 0).""" return [color] * size -def write_block(pos: int, block: List[int], field: List[int]) -> List[int]: +def write_block(pos: int, block: list[int], field: list[int]) -> list[int]: """Write a block into a field at given position.""" result = field.copy() for i, color in enumerate(block): @@ -15,7 +15,7 @@ def write_block(pos: int, block: List[int], field: List[int]) -> List[int]: return result -def task_move_n_pix(rng: Random, size: int, move_pix: int, solid: bool) -> Optional[Dict[str, List[int]]]: +def task_move_n_pix(rng: Random, size: int, move_pix: int, solid: bool) -> Optional[dict[str, list[int]]]: """Generate a task where a block is moved to the right by move_pix pixels.""" if size <= move_pix + 1: return None @@ -35,7 +35,7 @@ def task_move_n_pix(rng: Random, size: int, move_pix: int, solid: bool) -> Optio return {"input": question, "output": answer} -def task_move_n_pix_wrapped(rng: Random, size: int, move_pix: int, solid: bool) -> Optional[Dict[str, List[int]]]: +def task_move_n_pix_wrapped(rng: Random, size: int, move_pix: int, solid: bool) -> Optional[dict[str, list[int]]]: """Generate a task where a block is moved to the right by move_pix pixels with wrapping.""" block_size = rng.randint(1, size) block_pos = rng.randint(0, size) @@ -56,7 +56,7 @@ def task_move_n_pix_wrapped(rng: Random, size: int, move_pix: int, solid: bool) return {"input": question, "output": answer} -def task_gravity(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_gravity(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where all non-zero elements are attracted to the left.""" density = 0.5 question = [rng.randint(1, 9) if rng.random() < density else 0 for _ in range(size)] @@ -67,7 +67,7 @@ def task_gravity(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: return {"input": question, "output": answer} -def task_gravity_counting(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_gravity_counting(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where non-zero elements are counted and represented as a sequence of 1s.""" density = 0.5 question = [rng.randint(1, 9) if rng.random() < density else 0 for _ in range(size)] @@ -78,7 +78,7 @@ def task_gravity_counting(rng: Random, size: int) -> Optional[Dict[str, List[int return {"input": question, "output": answer} -def task_gravity_antigravity(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_gravity_antigravity(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where color 1 moves right and color 2 moves left.""" density = 0.5 question = [rng.randint(1, 2) if rng.random() < density else 0 for _ in range(size)] @@ -90,7 +90,7 @@ def task_gravity_antigravity(rng: Random, size: int) -> Optional[Dict[str, List[ return {"input": question, "output": answer} -def task_block_touch_dot(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_block_touch_dot(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block moves to touch (but not cover) a dot.""" dot_color = 1 block_color = rng.randint(2, 9) @@ -129,7 +129,7 @@ def task_block_touch_dot(rng: Random, size: int) -> Optional[Dict[str, List[int] return {"input": question, "output": answer} -def task_block_touch_dot_n_pix(rng: Random, size: int, move_pix: int) -> Optional[Dict[str, List[int]]]: +def task_block_touch_dot_n_pix(rng: Random, size: int, move_pix: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block moves move_pix pixels toward a dot.""" dot_color = 2 block_color = rng.randint(3, 9) @@ -172,7 +172,7 @@ def task_block_touch_dot_n_pix(rng: Random, size: int, move_pix: int) -> Optiona return {"input": question, "output": answer} -def task_block_scale_to_dot(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_block_scale_to_dot(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block scales to touch a dot (keeping one end fixed).""" dot_color = 2 block_color = rng.randint(3, 9) @@ -213,7 +213,7 @@ def task_block_scale_to_dot(rng: Random, size: int) -> Optional[Dict[str, List[i return {"input": question, "output": answer} -def task_two_points_and_fill(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_two_points_and_fill(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where space between two points of same color is filled with that color.""" color = rng.randint(1, 9) @@ -235,7 +235,7 @@ def task_two_points_and_fill(rng: Random, size: int) -> Optional[Dict[str, List[ return {"input": question, "output": answer} -def task_reflect_block_with_border_pixel(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_reflect_block_with_border_pixel(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block with a border pixel is reflected.""" block_size = rng.randint(2, size) if block_size > size: @@ -262,7 +262,7 @@ def task_reflect_block_with_border_pixel(rng: Random, size: int) -> Optional[Dic return {"input": question, "output": answer} -def task_reflect_block_with_border_pixel_random(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_reflect_block_with_border_pixel_random(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a random-colored block with a border pixel is reflected.""" block_size = rng.randint(2, size) if block_size > size: @@ -290,7 +290,7 @@ def task_reflect_block_with_border_pixel_random(rng: Random, size: int) -> Optio return {"input": question, "output": answer} -def task_reflect_block_around_dot(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_reflect_block_around_dot(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block is reflected around a dot.""" dot_color = 2 @@ -328,7 +328,7 @@ def task_reflect_block_around_dot(rng: Random, size: int) -> Optional[Dict[str, return {"input": question, "output": answer} -def task_block_and_noise_remove(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_block_and_noise_remove(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where noise around a block needs to be removed.""" block_size = rng.randint(2, size) if block_size > size: @@ -379,7 +379,7 @@ def task_block_and_noise_remove(rng: Random, size: int) -> Optional[Dict[str, Li return {"input": question, "output": answer} -def task_block_and_noise_remove_inside(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_block_and_noise_remove_inside(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where noise inside a block needs to be removed.""" if size <= 6: return None @@ -419,7 +419,7 @@ def task_block_and_noise_remove_inside(rng: Random, size: int) -> Optional[Dict[ return {"input": question, "output": answer} -def task_copy_block_to_dots(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_copy_block_to_dots(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block pattern is copied to dot positions.""" block_size = 3 if rng.random() < 0.5 else 5 if block_size >= size: @@ -456,7 +456,7 @@ def task_copy_block_to_dots(rng: Random, size: int) -> Optional[Dict[str, List[i return {"input": question, "output": answer} -def task_copy_block_to_dots_colors(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_copy_block_to_dots_colors(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block pattern is copied to dot positions with matching colors.""" block_size = 3 if rng.random() < 0.5 else 5 if block_size >= size: @@ -497,7 +497,7 @@ def task_copy_block_to_dots_colors(rng: Random, size: int) -> Optional[Dict[str, return {"input": question, "output": answer} -def task_paint_biggest_block(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_paint_biggest_block(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where the largest block is painted a different color.""" target_color = 1 initial_color = rng.randint(2, 9) @@ -535,7 +535,7 @@ def task_paint_biggest_block(rng: Random, size: int) -> Optional[Dict[str, List[ return {"input": question, "output": answer} -def task_sort_blocks_by_size(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_sort_blocks_by_size(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where blocks are sorted by size with 1 pixel gaps.""" color = rng.randint(1, 9) blocks = [] @@ -579,7 +579,7 @@ def task_sort_blocks_by_size(rng: Random, size: int) -> Optional[Dict[str, List[ return {"input": question, "output": answer} -def task_sort_complete_sequence(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_sort_complete_sequence(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a complete sequence of block sizes is sorted.""" # Calculate max possible block size given total array size max_size = 1 @@ -617,7 +617,7 @@ def task_sort_complete_sequence(rng: Random, size: int) -> Optional[Dict[str, Li return {"input": question, "output": answer} -def task_recolor_blocks_by_size(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_recolor_blocks_by_size(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where two blocks are recolored based on their size.""" # Generate two different random sizes size1 = rng.randint(2, 8) @@ -656,7 +656,7 @@ def task_recolor_blocks_by_size(rng: Random, size: int) -> Optional[Dict[str, Li return {"input": question, "output": answer} -def task_gravity_one_step(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_gravity_one_step(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where non-zero elements move one step left if possible.""" question = [rng.randint(1, 9) if rng.random() < 0.5 else 0 for _ in range(size)] answer = question.copy() @@ -670,7 +670,7 @@ def task_gravity_one_step(rng: Random, size: int) -> Optional[Dict[str, List[int return {"input": question, "output": answer} -def task_move_block_by_own_size(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_move_block_by_own_size(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block moves right by its own size.""" block_size = rng.randint(1, size // 2) # Ensure space for movement pos = rng.randint(0, size - block_size * 2) # Space for block and movement @@ -685,7 +685,7 @@ def task_move_block_by_own_size(rng: Random, size: int) -> Optional[Dict[str, Li return {"input": question, "output": answer} -def task_change_to_five(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_change_to_five(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where all non-zero colors change to 5.""" density = 0.5 question = [rng.randint(1, 9) if rng.random() < density else 0 for _ in range(size)] @@ -694,7 +694,7 @@ def task_change_to_five(rng: Random, size: int) -> Optional[Dict[str, List[int]] return {"input": question, "output": answer} -def task_recolor_blocks_from_palette(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_recolor_blocks_from_palette(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where blocks are recolored using a color palette.""" # Generate blocks of same size block_size = rng.randint(2, 4) @@ -750,7 +750,7 @@ def task_recolor_blocks_from_palette(rng: Random, size: int) -> Optional[Dict[st return {"input": question, "output": answer} -def task_duplicate_block_from_seeds(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_duplicate_block_from_seeds(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a block is duplicated from seed pixels.""" block_size = rng.randint(2, 4) if block_size + 1 >= size: @@ -812,7 +812,7 @@ def task_duplicate_block_from_seeds(rng: Random, size: int) -> Optional[Dict[str return {"input": question, "output": answer} -def task_fill_from_pixel(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_fill_from_pixel(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a pixel fills in one direction until hitting another pixel.""" block_size = rng.randint(3, 6) if block_size >= size - 2: @@ -856,7 +856,7 @@ def task_fill_from_pixel(rng: Random, size: int) -> Optional[Dict[str, List[int] return {"input": question, "output": answer} -def task_mark_size_two_blocks(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_mark_size_two_blocks(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where size-2 blocks are marked with surrounding pixels.""" blocks = [] pos = 0 @@ -908,7 +908,7 @@ def task_mark_size_two_blocks(rng: Random, size: int) -> Optional[Dict[str, List return {"input": question, "output": answer} -def task_fill_until_collision(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_fill_until_collision(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where pixels fill empty space until collision.""" # At least 4 positions for meaningful puzzle if size < 4: @@ -975,7 +975,7 @@ def task_fill_until_collision(rng: Random, size: int) -> Optional[Dict[str, List return {"input": question, "output": answer} -def task_repeat_pattern_full(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_repeat_pattern_full(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where a pattern is repeated to fill the space.""" # Generate initial pattern pattern_size = rng.randint(2, 5) @@ -1007,7 +1007,7 @@ def task_repeat_pattern_full(rng: Random, size: int) -> Optional[Dict[str, List[ return {"input": question, "output": answer} -def task_gravity_weighted_colors(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_gravity_weighted_colors(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where color 2 is heavier than color 1 in gravity.""" # Generate random field with only colors 1 and 2 question = [rng.randint(1, 2) if rng.random() < 0.5 else 0 for _ in range(size)] @@ -1030,7 +1030,7 @@ def task_gravity_weighted_colors(rng: Random, size: int) -> Optional[Dict[str, L return {"input": question, "output": answer} -def task_color_left_half_blocks(rng: Random, size: int) -> Optional[Dict[str, List[int]]]: +def task_color_left_half_blocks(rng: Random, size: int) -> Optional[dict[str, list[int]]]: """Generate a task where left half of blocks are colored differently.""" pos = 0 question = gen_field(size) @@ -1063,21 +1063,21 @@ def task_color_left_half_blocks(rng: Random, size: int) -> Optional[Dict[str, Li return {"input": question, "output": answer} -def task_mirror(task_result: Optional[Dict[str, List[int]]]) -> Optional[Dict[str, List[int]]]: +def task_mirror(task_result: Optional[dict[str, list[int]]]) -> Optional[dict[str, list[int]]]: """Mirror the input and output arrays of a task result.""" if task_result is None: return None return {"input": list(reversed(task_result["input"])), "output": list(reversed(task_result["output"]))} -def task_inverse(task_result: Optional[Dict[str, List[int]]]) -> Optional[Dict[str, List[int]]]: +def task_inverse(task_result: Optional[dict[str, list[int]]]) -> Optional[dict[str, list[int]]]: """Swap the input and output arrays of a task result.""" if task_result is None: return None return {"input": task_result["output"], "output": task_result["input"]} -def task_identity(task_result: Optional[Dict[str, List[int]]]) -> Optional[Dict[str, List[int]]]: +def task_identity(task_result: Optional[dict[str, list[int]]]) -> Optional[dict[str, list[int]]]: """Return the task result unchanged.""" return task_result diff --git a/reasoning_gym/arc/board_format.py b/reasoning_gym/arc/board_format.py index 554ba299..b0a40636 100644 --- a/reasoning_gym/arc/board_format.py +++ b/reasoning_gym/arc/board_format.py @@ -1,5 +1,4 @@ from dataclasses import dataclass, field -from typing import List, Tuple ARC_PROMPT_TEMPLATE = """Find the common rule that maps an input grid to an output grid, given the examples below. @@ -21,7 +20,7 @@ class BoardFormattingOptions: def format_board( - board: List[List[int]], formatting_options: BoardFormattingOptions, with_board_shape: bool = False + board: list[list[int]], formatting_options: BoardFormattingOptions, with_board_shape: bool = False ) -> str: """ Format a board as a string @@ -65,7 +64,7 @@ def format_board( def format_board_pair( index: int, - pair: dict[str, List[List[int]]], + pair: dict[str, list[list[int]]], formatting_options: BoardFormattingOptions, ) -> str: """ @@ -82,7 +81,7 @@ def format_board_pair( return f"Example {index}:\n\nInput:\n{input_element}\nOutput:\n{output_element}\n\n" -def parse_board(formatted_str: str, formatting_options: BoardFormattingOptions) -> Tuple[Tuple[int, ...], ...]: +def parse_board(formatted_str: str, formatting_options: BoardFormattingOptions) -> tuple[tuple[int, ...], ...]: """ Convert a formatted board string back to a tuple grid using formatting options """ diff --git a/reasoning_gym/arc/rearc.py b/reasoning_gym/arc/rearc.py index ac362f9a..35712705 100644 --- a/reasoning_gym/arc/rearc.py +++ b/reasoning_gym/arc/rearc.py @@ -95,7 +95,7 @@ class ReArcDataset(ProceduralDataset): }, } - def score_answer(self, answer: str, entry: Dict[str, Any]) -> float: + def score_answer(self, answer: str, entry: dict[str, Any]) -> float: reward = 0.0 metadata = entry["metadata"] if answer is not None: diff --git a/reasoning_gym/arc/rearc_utils/utils.py b/reasoning_gym/arc/rearc_utils/utils.py index a6fe0ff4..456c50e4 100644 --- a/reasoning_gym/arc/rearc_utils/utils.py +++ b/reasoning_gym/arc/rearc_utils/utils.py @@ -1,5 +1,5 @@ import random -from typing import Any, List, Tuple +from typing import Any from .dsl import * @@ -40,7 +40,7 @@ def get_pso_difficulty(example: dict) -> float: return (pix_pct + col_pct + obj_dens) / 3 -def unifint(rng: random.Random, diff_lb: float, diff_ub: float, bounds: Tuple[int, int]) -> int: +def unifint(rng: random.Random, diff_lb: float, diff_ub: float, bounds: tuple[int, int]) -> int: """ rng diff_lb: lower bound for difficulty, must be in range [0, diff_ub] @@ -83,7 +83,7 @@ def strip_prefix(string: str, prefix: str) -> str: return string[len(prefix) :] -def format_grid(grid: List[List[int]]) -> Grid: +def format_grid(grid: list[list[int]]) -> Grid: """ grid type casting """ diff --git a/reasoning_gym/arithmetic/basic_arithmetic.py b/reasoning_gym/arithmetic/basic_arithmetic.py index 3075dd28..4fc62bad 100644 --- a/reasoning_gym/arithmetic/basic_arithmetic.py +++ b/reasoning_gym/arithmetic/basic_arithmetic.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Any, Dict, Literal, Optional +from typing import Any, Literal, Optional from reasoning_gym import utils @@ -234,7 +234,7 @@ class BasicArithmeticDataset(ProceduralDataset): template = rng.choice(templates) return template.format(expression) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: oracle_answer = entry["answer"].strip() return utils.compute_reward(answer, oracle_answer, allow_commas=False) diff --git a/reasoning_gym/arithmetic/calendar_arithmetic.py b/reasoning_gym/arithmetic/calendar_arithmetic.py index 3a052590..9b307001 100644 --- a/reasoning_gym/arithmetic/calendar_arithmetic.py +++ b/reasoning_gym/arithmetic/calendar_arithmetic.py @@ -4,7 +4,7 @@ import random from dataclasses import dataclass from datetime import date, timedelta from enum import Enum, StrEnum, auto -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -51,7 +51,7 @@ class CalendarTask(StrEnum): @dataclass class CalendarArithmeticConfig: year: int = 2022 - tasks: Optional[List[str]] = None + tasks: Optional[list[str]] = None offset_upper_bound: int = 100 leap_year_range: int = 200 seed: Optional[int] = 42 @@ -131,7 +131,7 @@ class CalendarArithmeticDataset(ProceduralDataset): "metadata": metadata, } - def _weekday_offset(self, rng: random.Random) -> Tuple[str, str, dict]: + def _weekday_offset(self, rng: random.Random) -> tuple[str, str, dict]: """ Task: Given a starting date and a day offset (which may be positive or negative), ask what day of the week it will be. @@ -170,7 +170,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, target_weekday, metadata - def _weekday_of_date(self, rng: random.Random) -> Tuple[str, str, dict]: + def _weekday_of_date(self, rng: random.Random) -> tuple[str, str, dict]: """ task: Ask what day of the week a given date was. example: @@ -193,7 +193,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, answer_weekday, metadata - def _weekday_of_date_from_first_day(self, rng: random.Random) -> Tuple[str, str, dict]: + def _weekday_of_date_from_first_day(self, rng: random.Random) -> tuple[str, str, dict]: """ task: Given an hypothetical weekday for January 1, ask what weekday a later date in the year falls on. example: @@ -235,7 +235,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, answer_weekday, metadata - def _recurring_event_day(self, rng: random.Random) -> Tuple[str, str, dict]: + def _recurring_event_day(self, rng: random.Random) -> tuple[str, str, dict]: """ task: For a recurring event defined by an ordinal weekday pattern in a month, ask on which day of the month the event occurs. @@ -294,7 +294,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, str(event_day), metadata - def _count_days(self, rng: random.Random) -> Tuple[str, str, dict]: + def _count_days(self, rng: random.Random) -> tuple[str, str, dict]: """ task: Ask how many times a given weekday occurs in a specified range. example: @@ -334,7 +334,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, str(count), metadata - def _count_business_days(self, rng: random.Random) -> Tuple[str, str, dict]: + def _count_business_days(self, rng: random.Random) -> tuple[str, str, dict]: """ task: Count the number of business days (Monday-Friday) between two dates. example: @@ -385,7 +385,7 @@ class CalendarArithmeticDataset(ProceduralDataset): } return question, str(count), metadata - def _is_leap_year(self, rng: random.Random) -> Tuple[str, str, dict]: + def _is_leap_year(self, rng: random.Random) -> tuple[str, str, dict]: """ task: Given a year, determine whether it is a leap year. example: @@ -426,7 +426,7 @@ class CalendarArithmeticDataset(ProceduralDataset): random_days = rng.randint(0, delta) return start_date + timedelta(days=random_days) - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: # we suppose the answer is the last occurence of the expected answer type if answer is None: return 0.0 diff --git a/reasoning_gym/arithmetic/chain_sum.py b/reasoning_gym/arithmetic/chain_sum.py index 4a5d68c1..04d79d29 100644 --- a/reasoning_gym/arithmetic/chain_sum.py +++ b/reasoning_gym/arithmetic/chain_sum.py @@ -1,6 +1,6 @@ import random from dataclasses import dataclass -from typing import Dict, Optional +from typing import Any, Optional from reasoning_gym import utils @@ -110,7 +110,7 @@ class ChainSumDataset(ProceduralDataset): expression = " ".join(expression_parts) return expression, result - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: oracle_answer = entry["answer"].strip() return utils.compute_reward(answer, oracle_answer) diff --git a/reasoning_gym/arithmetic/decimal_arithmetic.py b/reasoning_gym/arithmetic/decimal_arithmetic.py index 881c004a..9d311bbf 100644 --- a/reasoning_gym/arithmetic/decimal_arithmetic.py +++ b/reasoning_gym/arithmetic/decimal_arithmetic.py @@ -2,7 +2,7 @@ import ast from dataclasses import dataclass from decimal import ROUND_HALF_UP, Decimal, getcontext from random import Random -from typing import Any, Dict, List, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -25,7 +25,7 @@ class DecimalArithmeticConfig: ), "precision must be 2 or more higher than max_num_decimal_places" -def build_grouped_expression(operands: List[str], operators: List[str], rng: Random) -> str: +def build_grouped_expression(operands: list[str], operators: list[str], rng: Random) -> str: """ Recursively build an arithmetic expression string from operands and operators, inserting parentheses at random. @@ -53,7 +53,7 @@ def generate_arithmetic_problem( min_num_decimal_places: int, max_num_decimal_places: int, terms: int = 2, - operations: Optional[List[str]] = None, + operations: Optional[list[str]] = None, ) -> str: """ Generates a simple arithmetic problem with decimal numbers (as a string) formatted @@ -72,8 +72,8 @@ def generate_arithmetic_problem( if operations is None: operations = ["+", "-", "*", "/"] - operands: List[str] = [] - operators: List[str] = [] + operands: list[str] = [] + operators: list[str] = [] for i in range(terms): # Choose a random number of decimal places for this term. @@ -149,7 +149,7 @@ class DecimalArithmeticDataset(ProceduralDataset): def __init__(self, config: DecimalArithmeticConfig) -> None: super().__init__(config=config, seed=config.seed, size=config.size) - def __getitem__(self, idx: int) -> Dict[str, Any]: + def __getitem__(self, idx: int) -> dict[str, Any]: """ Generate a single arithmetic task. @@ -180,7 +180,7 @@ class DecimalArithmeticDataset(ProceduralDataset): return {"question": problem_str, "answer": answer, "metadata": {}} - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """ Compares the user's answer (converted to Decimal) with the correct answer. Instead of requiring exact equality, we allow an error up to one unit in the diff --git a/reasoning_gym/arithmetic/decimal_chain_sum.py b/reasoning_gym/arithmetic/decimal_chain_sum.py index da920c9d..8e20ed59 100644 --- a/reasoning_gym/arithmetic/decimal_chain_sum.py +++ b/reasoning_gym/arithmetic/decimal_chain_sum.py @@ -133,7 +133,7 @@ class DecimalChainSumDataset(ProceduralDataset): result = result.quantize(Decimal(f"0.{'0' * max(decimal_places)}")) return expression, result - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Score the answer by comparing decimal values instead of strings. Args: answer: The answer to score diff --git a/reasoning_gym/arithmetic/dice.py b/reasoning_gym/arithmetic/dice.py index f4ad97e9..0dcf3e44 100644 --- a/reasoning_gym/arithmetic/dice.py +++ b/reasoning_gym/arithmetic/dice.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from functools import reduce from math import gcd from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -125,14 +125,14 @@ class DiceDataset(ProceduralDataset): "metadata": {}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the Dice task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/arithmetic/fraction_simplification.py b/reasoning_gym/arithmetic/fraction_simplification.py index bd80fd70..d0cc2cb8 100644 --- a/reasoning_gym/arithmetic/fraction_simplification.py +++ b/reasoning_gym/arithmetic/fraction_simplification.py @@ -4,7 +4,7 @@ import re from dataclasses import dataclass from math import gcd from random import Random -from typing import Any, Dict, Optional, Sequence, Tuple +from typing import Any, Optional, Sequence from ..factory import ProceduralDataset, register_dataset @@ -42,7 +42,7 @@ class FractionSimplificationDataset(ProceduralDataset): def __init__(self, config: FractionSimplificationConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _generate_fraction(self, rng: Random) -> Tuple[int, int, int, int]: + def _generate_fraction(self, rng: Random) -> tuple[int, int, int, int]: """Generate a random fraction and its simplified form. Returns (numerator, denominator, simplified_num, simplified_den)""" # Try to generate valid fractions until we get one that meets our criteria @@ -134,7 +134,7 @@ class FractionSimplificationDataset(ProceduralDataset): except: return None - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]): + def score_answer(self, answer: Optional[str], entry: dict[str, Any]): reward = 0.0 metadata = entry["metadata"] try: diff --git a/reasoning_gym/arithmetic/gcd.py b/reasoning_gym/arithmetic/gcd.py index 0c25797f..a764b2bd 100644 --- a/reasoning_gym/arithmetic/gcd.py +++ b/reasoning_gym/arithmetic/gcd.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from functools import reduce from math import gcd from random import Random -from typing import List, Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -34,7 +34,7 @@ class GCDDataset(ProceduralDataset): def __init__(self, config: GCDConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _generate_numbers(self, rng: Random) -> Tuple[List[int], int]: + def _generate_numbers(self, rng: Random) -> tuple[list[int], int]: """Generate a list of random positive integers and their GCD. Will try up to 3 times to find numbers with GCD > 1.""" diff --git a/reasoning_gym/arithmetic/gsm_symbolic/generators_00_49.py b/reasoning_gym/arithmetic/gsm_symbolic/generators_00_49.py index fb8d170b..eea9429b 100644 --- a/reasoning_gym/arithmetic/gsm_symbolic/generators_00_49.py +++ b/reasoning_gym/arithmetic/gsm_symbolic/generators_00_49.py @@ -6,11 +6,11 @@ from typing import Any, Dict from reasoning_gym.utils import format_number, is_integer -def generate_0(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_0(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, food: str, peel_rate: int, batch_size: int, time_per_batch: int, total_amount: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: peel_time = total_amount // peel_rate num_batches = total_amount // batch_size @@ -44,7 +44,7 @@ def generate_0(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emily", "Sarah", "Emma", "Sophia", "Olivia", "Ava", "Isabella", "Mia"] foods = ["shrimp", "onion", "carrot", "mushroom", "clam"] @@ -76,11 +76,11 @@ def generate_0(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_1(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_1(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, family: str, blocks: int, animals: int, rings: int, total: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: bouncy_balls = total - (blocks + animals + rings) question = f"When {name} watches her {family}, she gets out a variety of toys for him. The bag of building blocks has {blocks} blocks in it. The bin of stuffed animals has {animals} stuffed animals inside. The tower of stacking rings has {rings} multicolored rings on it. {name} recently bought a tube of bouncy balls, bringing her total number of toys for her {family} up to {total}. How many bouncy balls came in the tube?" @@ -103,7 +103,7 @@ def generate_1(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Sophie", "Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia"] family_members = ["nephew", "cousin", "brother"] @@ -132,11 +132,11 @@ def generate_1(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_2(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_2(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( teacher: str, total: int, p1: int, p2: int, group1: str, group2: str, group3: str, event: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: group1_count = int(total * p1 / 100) remaining = total - group1_count group23_count = int(remaining * p2 / 100) @@ -171,7 +171,7 @@ def generate_2(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: teachers = ["Ms. Johnson", "Mr. Smith", "Dr. Lee", "Mrs. Garcia"] sports = ["soccer players", "basketball players", "volleyball players", "swimmers"] activities = ["dancers", "choir members", "debate team members", "robotics club members"] @@ -220,7 +220,7 @@ def generate_2(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_3(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_3(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -229,7 +229,7 @@ def generate_3(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: letters_per_week: int, pages_per_letter: int, minutes_per_page: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: current_pals = initial_pals - lost_pals letters_received = current_pals * letters_per_week pages_to_write = letters_received * pages_per_letter @@ -263,7 +263,7 @@ def generate_3(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Mike", "John", "David", "James", "Robert", "William", "Richard"] name = rng.choice(names) @@ -312,11 +312,11 @@ def generate_3(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_4(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_4(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, items: str, food: str, location: str, container: str, num_jars: int, per_jar: int, per_pan: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_items = num_jars * per_jar num_pans = total_items // per_pan @@ -342,7 +342,7 @@ def generate_4(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Mary", "Sarah", "Emma", "Elizabeth", "Catherine"] items = ["sprinkles", "frosting", "icing", "chocolate chips"] foods = ["cupcake", "cookie", "brownie", "muffin"] @@ -383,7 +383,7 @@ def generate_4(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_5(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_5(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, @@ -396,7 +396,7 @@ def generate_5(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: s1: int, s2: int, goal: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: signatures_collected = s1 + s2 signatures_needed = goal - signatures_collected @@ -425,7 +425,7 @@ def generate_5(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Carol", "Jennifer"] cities = ["Los Angeles", "New York", "Chicago", "Houston", "Phoenix"] celebrity_types = ["movie stars", "athletes", "musicians", "politicians", "authors"] @@ -463,9 +463,9 @@ def generate_5(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_6(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_6(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(n_girls: int, place: str, multiplier: int) -> Dict[str, Any]: + def generate_from_variables(n_girls: int, place: str, multiplier: int) -> dict[str, Any]: n_boys = n_girls * multiplier total_kids = n_girls + n_boys @@ -487,7 +487,7 @@ def generate_6(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: places = ["park", "yard", "field", "playground", "garden"] multipliers = [2, 3, 4] # twice, triple, quadruple @@ -515,11 +515,11 @@ def generate_6(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_7(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_7(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, plants_received: int, plants_per_ledge: int, num_ledges: int, plants_to_give: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: initial_plants = plants_per_ledge * num_ledges total_plants = initial_plants + plants_received @@ -548,7 +548,7 @@ def generate_7(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Mary", "Emma", "Sophia", "Isabella", "Olivia", "Ava", "Mia"] name = rng.choice(names) @@ -578,11 +578,11 @@ def generate_7(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_8(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_8(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, drink: str, sugar_ratio: int, water_ratio: int, total_items: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_ratio = sugar_ratio + water_ratio sugar_amount = (sugar_ratio * total_items) // total_ratio @@ -605,7 +605,7 @@ def generate_8(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte"] drinks = ["coffee", "tea"] @@ -636,7 +636,7 @@ def generate_8(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_9(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_9(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -649,7 +649,7 @@ def generate_9(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: item1: str, item2: str, currency: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: initial_amount = num_bills * bill_value spent_items1 = num_items1 * price1 @@ -688,7 +688,7 @@ def generate_9(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Craig", "John", "Michael", "David", "James", "Robert", "William"] items1 = ["toy car", "action figure", "coloring book", "puzzle", "board game"] items2 = ["sticker", "candy bar", "trading card", "pencil", "eraser"] @@ -745,11 +745,11 @@ def generate_9(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_10(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_10(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, name2: str, age1: int, years: int, relation_type: str, mult: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: future_age = age1 * mult current_age = future_age - years @@ -774,7 +774,7 @@ def generate_10(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_male = ["James", "John", "Robert", "Michael", "William", "David", "Richard"] names_female = ["Mary", "Patricia", "Jennifer", "Linda", "Elizabeth", "Barbara", "Susan"] relation_types = ["sister", "cousin"] @@ -809,9 +809,9 @@ def generate_10(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_11(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_11(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, food1: str, food2: str, mult: int, n: int, m: int, k: int) -> Dict[str, Any]: + def generate_from_variables(name: str, food1: str, food2: str, mult: int, n: int, m: int, k: int) -> dict[str, Any]: # Initial amounts initial_food2 = n # Initial amount of food2 initial_food1 = n * mult # Initial amount of food1 (mult times food2) @@ -872,7 +872,7 @@ def generate_11(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Allan", "John", "Michael", "David", "James", "Robert", "William"] foods = ["corn", "apple", "banana", "orange", "pear", "grape", "fig", "persimmon", "plum", "kiwi"] @@ -900,11 +900,11 @@ def generate_11(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_12(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_12(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, game1: str, game2: str, period: str, time1: int, time2: int, num1: int, num2: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_time1 = time1 * num1 total_time2 = time2 * num2 total_time = total_time1 + total_time2 @@ -937,7 +937,7 @@ def generate_12(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte"] games = ["word puzzle", "jigsaw puzzle", "chess puzzle", "riddle", "brain teaser"] periods = ["weekend", "vacation", "holiday", "day off", "free time"] @@ -971,11 +971,11 @@ def generate_12(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_13(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_13(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( park_name: str, unit: str, length1: int, length2: int, speed1: int, speed2: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: time1 = length1 // speed1 time2 = length2 // speed2 time_diff = time1 - time2 @@ -1001,7 +1001,7 @@ def generate_13(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: parks = ["Splash World", "Aqua Adventure", "Water Wonderland", "Neptunes Kingdom"] units = ["yards", "meters"] @@ -1050,11 +1050,11 @@ def generate_13(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_14(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_14(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, day1: str, day2: str, day3: str, time1: int, time2: int, mult: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: combined_time = time1 + time2 target_time = combined_time * mult @@ -1080,7 +1080,7 @@ def generate_14(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Peter", "John", "Michael", "David", "James", "Robert", "William"] weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] multipliers = [2, 3, 4] @@ -1122,7 +1122,7 @@ def generate_14(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_15(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_15(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -1137,7 +1137,7 @@ def generate_15(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: price3: int, price4: int, discount: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: shorts_price = price1 + price2 shoes_price = price3 // 2 @@ -1169,7 +1169,7 @@ def generate_15(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Amelia"] sports = ["swimming", "cycling", "basketball", "soccer", "volleyball"] items1 = ["t-shirt", "jersey", "sports bra"] @@ -1212,11 +1212,11 @@ def generate_15(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_16(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_16(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, name2: str, name3: str, platform: str, mult1: int, mult2: int, n: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: base_friends = n // mult1 # Dorothy's friends charlie_friends = n # Charlie's friends james_friends = base_friends * mult2 # James's friends @@ -1243,7 +1243,7 @@ def generate_16(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Charlie", "Dorothy", "James", "Sarah", "Michael", "Emily", "David"] platforms = ["Instagram", "Twitter", "LinkedIn", "TikTok", "Snapchat"] @@ -1276,11 +1276,11 @@ def generate_16(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_17(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_17(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( facility: str, total: int, item: str, frac: Fraction, event: str, daily: int, period: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: initial_occupied = int(total * frac) initial_empty = total - initial_occupied weekly_admitted = daily * 7 @@ -1310,7 +1310,7 @@ def generate_17(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: facilities = ["hospital", "clinic", "medical center", "care facility"] items = ["bed", "room", "ward"] events = ["flu season", "natural disaster", "major accident", "pandemic"] @@ -1365,9 +1365,9 @@ def generate_17(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_18(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_18(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name1: str, name2: str, game: str, n1: int, n2: int, frac: float) -> Dict[str, Any]: + def generate_from_variables(name1: str, name2: str, game: str, n1: int, n2: int, frac: float) -> dict[str, Any]: score2 = int(frac * n1 + n2) total = n1 + score2 @@ -1392,7 +1392,7 @@ def generate_18(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = [ "James", "John", @@ -1445,11 +1445,11 @@ def generate_18(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_19(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_19(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, pan: str, initial_kernels: int, time_interval: int, multiplier_2: int, multiplier_3: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: second_interval = multiplier_2 * initial_kernels third_interval = multiplier_3 * initial_kernels fourth_interval = third_interval // 2 @@ -1480,7 +1480,7 @@ def generate_19(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Garrett", "James", "Michael", "David", "John", "Robert", "William"] pans = ["pan", "pot", "skillet"] @@ -1514,11 +1514,11 @@ def generate_19(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_20(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_20(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, obj: str, surface: str, capacity: int, total: int, num_trays: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: max_capacity = capacity * num_trays leftover = total - max_capacity @@ -1543,7 +1543,7 @@ def generate_20(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard"] objects = ["olive", "almond", "cookie", "cracker", "banana"] surfaces = ["plate", "table", "bowl", "tray", "basket"] @@ -1575,11 +1575,11 @@ def generate_20(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_21(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_21(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, length: int, unit_length: str, plant_width: int, space: float, owned: int, currency: str, cost: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_plants = int(length / space) plants_to_buy = total_plants - owned total_cost = plants_to_buy * cost @@ -1630,7 +1630,7 @@ def generate_21(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte"] currencies = ["$", "£", "€"] units = ["feet", "meters"] @@ -1673,11 +1673,11 @@ def generate_21(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_22(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_22(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, property_type: str, budget: int, price: int, brokerage_fee: int, transfer_fee: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: brokerage_amount = int(price * brokerage_fee / 100) transfer_amount = int(price * transfer_fee / 100) total_price = price + brokerage_amount + transfer_amount @@ -1705,7 +1705,7 @@ def generate_22(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Mrs. Smith", "Ms. Johnson", "Dr. Patel", "Mrs. Lee"] property_types = ["house", "apartment", "condo", "townhouse"] @@ -1741,11 +1741,11 @@ def generate_22(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_23(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_23(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, task: str, profession: str, hours: int, work_type: str, rate: int, fee: int, currency: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: lost_income = hours * rate savings = lost_income - fee @@ -1771,7 +1771,7 @@ def generate_23(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Sophia", "Isabella", "Olivia", "Ava", "Mia", "Emily"] tasks = ["her taxes", "her financial planning", "her business accounting"] professions = ["accountant", "financial advisor", "tax consultant", "bookkeeper"] @@ -1810,11 +1810,11 @@ def generate_23(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_24(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_24(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( comet_name: str, name: str, relative: str, orbit_period: int, relative_age: int, multiple: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: second_viewing_age = relative_age * multiple first_viewing_age = second_viewing_age - orbit_period @@ -1839,7 +1839,7 @@ def generate_24(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: comets = ["Halley", "Hale-Bopp", "Hyakutake", "Encke"] names = ["William", "James", "John", "Robert", "Michael", "David"] relatives = ["dad", "father", "uncle", "grandfather"] @@ -1884,11 +1884,11 @@ def generate_24(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_25(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_25(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( food: str, calories: int, size: int, servings: int, total_target: int, consumed: int, unit: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: calories_left = total_target - consumed serving_fraction = Fraction(calories_left, calories) @@ -1924,7 +1924,7 @@ def generate_25(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: foods = ["popcorn", "breads", "cookies"] units = ["grams", "ounces", "oz"] @@ -1975,9 +1975,9 @@ def generate_25(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_26(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_26(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(n: int, ball_type: str, color: str, frac_1: float, frac_2: float) -> Dict[str, Any]: + def generate_from_variables(n: int, ball_type: str, color: str, frac_1: float, frac_2: float) -> dict[str, Any]: first_calc = int(n * frac_1) final_calc = int(first_calc * frac_2) @@ -2001,7 +2001,7 @@ def generate_26(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: ball_types = ["golf", "tennis"] colors = ["blue", "red", "green", "yellow", "white"] fractions = [0.5, 0.25, 0.75] @@ -2032,7 +2032,7 @@ def generate_26(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_27(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_27(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -2043,7 +2043,7 @@ def generate_27(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: freq: int, rate: float, currency: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: first_two = n_first * apartments_each third_complex = int(first_two * percent_bigger / 100) @@ -2082,7 +2082,7 @@ def generate_27(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "Robert", "William"] currencies = ["$", "£", "€"] @@ -2118,7 +2118,7 @@ def generate_27(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_28(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_28(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -2130,7 +2130,7 @@ def generate_28(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: extra_price: float, currency: str, unit: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: price_increase = price * percent / 100 new_price = price + price_increase weekly_usage = usage * 7 @@ -2161,7 +2161,7 @@ def generate_28(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_male = ["John", "Michael", "David", "James", "Robert", "William", "Richard", "Thomas"] items = ["tea", "sugar", "flour", "rice"] currencies_sym = ["$", "£", "€"] @@ -2199,9 +2199,9 @@ def generate_28(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_29(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_29(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name1: str, name2: str, n1: int, n2: int, k1: int, k2: int) -> Dict[str, Any]: + def generate_from_variables(name1: str, name2: str, n1: int, n2: int, k1: int, k2: int) -> dict[str, Any]: total_puppies = n1 + n2 spotted_puppies = k1 + k2 percentage = int(100 * spotted_puppies / total_puppies) @@ -2232,7 +2232,7 @@ def generate_29(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = [ "Jennifer", "Michael", @@ -2307,11 +2307,11 @@ def generate_29(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_30(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_30(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( group: str, n: int, n_1: int, n_2: int, hobby1: str, hobby2: str, hobby3: str, hobby4: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n_4 = 2 * n_2 # number that like hobby4 (music) n_3 = n - (n_1 + n_2 + n_4) # number that like hobby3 (video games) @@ -2338,7 +2338,7 @@ def generate_30(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: groups = ["group", "class"] hobbies = ["read", "paint", "hike", "dance", "bake", "play video games", "play music"] sports = ["basketball", "soccer", "tennis", "baseball", "volleyball"] @@ -2374,11 +2374,11 @@ def generate_30(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_31(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_31(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, fruit: str, total: int, n1: int, n2: int, n3: int, sibling1: str, sibling2: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: slice2 = n1 + n2 slice3 = slice2 + n3 total_eaten = n1 + slice2 + slice3 @@ -2405,7 +2405,7 @@ def generate_31(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Doxa"] fruits = ["orange", "pear", "peach", "mango", "kiwi", "apple"] siblings = ["brother", "sister", "cousin", "friend"] @@ -2454,11 +2454,11 @@ def generate_31(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_32(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_32(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, periods: int, extra_classes: int, mins_per_class: int, days: int, weekend_fraction: float - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_classes = periods + extra_classes daily_mins = total_classes * mins_per_class weekly_mins = daily_mins * days @@ -2497,7 +2497,7 @@ def generate_32(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "James", "William", "Michael", "David", "Richard", "Thomas"] fractions = ["1/16", "1/8", "1/4", "1/2"] @@ -2540,9 +2540,9 @@ def generate_32(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_33(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_33(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name1: str, name2: str, mult: int, n: int) -> Dict[str, Any]: + def generate_from_variables(name1: str, name2: str, mult: int, n: int) -> dict[str, Any]: n_mult = n * mult daily_total = n + n_mult weekly_total = daily_total * 7 @@ -2572,7 +2572,7 @@ def generate_33(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Julie", "Sarah", "Emma", "Sophia", "Olivia", "Isabella", "Mia", "Charlotte"] multi_times = [2, 3, 4] @@ -2617,9 +2617,9 @@ def generate_33(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_34(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_34(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(event: str, item: str, family: str, n: int, m: int, total: int) -> Dict[str, Any]: + def generate_from_variables(event: str, item: str, family: str, n: int, m: int, total: int) -> dict[str, Any]: twins_total = 2 * n remaining = total - twins_total friends_found = remaining - m @@ -2645,7 +2645,7 @@ def generate_34(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: events = ["Halloween candy hunt", "Treasure hunt", "Scavenger hunt", "Charity fundraiser"] items = ["eggs", "treats", "toys", "coins", "tokens", "balls", "candies", "goodies"] families = ["Johnson", "Williams", "Mirzakhani", "Lopez", "Garcia", "Lee"] @@ -2679,11 +2679,11 @@ def generate_34(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_35(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_35(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( job: str, building: str, room: str, num_rooms: int, num_days: int, time_per_room: int, hours_per_day: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: # Calculate values ensuring integer percentage rooms_per_day = num_rooms // num_days # Integer division for rooms per day @@ -2722,7 +2722,7 @@ def generate_35(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: jobs = ["janitor", "cleaner", "maintenance worker"] buildings = ["office building", "hospital", "university"] rooms = ["room", "floor"] @@ -2774,9 +2774,9 @@ def generate_35(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_36(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_36(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(n: int, p1: int, r1: int, name: str, s1: str, s2: str, s3: str) -> Dict[str, Any]: + def generate_from_variables(n: int, p1: int, r1: int, name: str, s1: str, s2: str, s3: str) -> dict[str, Any]: easy_questions = int(n * (p1 / 100)) other_questions = int(n * (1 - p1 / 100)) easy_correct = int(easy_questions * (r1 / 100)) @@ -2814,7 +2814,7 @@ def generate_36(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: subjects = [ "history", "geography", @@ -2861,11 +2861,11 @@ def generate_36(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_37(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_37(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( worker: str, base: int, unit: str, tool1: str, tool2: str, tool3: str, mult1: int, mult2: int, n: int, days: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: iron_amount = base * mult1 steel_amount = int(iron_amount * (1 + mult2 / 100)) daily_total = steel_amount * n @@ -2903,7 +2903,7 @@ def generate_37(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: workers = ["miner", "goblin", "gnome", "troll"] tools1 = ["bare hands", "basic shovel", "wooden pickaxe"] units = ["pounds", "kgs"] @@ -2962,7 +2962,7 @@ def generate_37(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_38(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_38(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -2978,7 +2978,7 @@ def generate_38(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: n3: int, n4: int, n5: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: skeins_per_child = n1 + n2 + n3 + n4 + n5 total_skeins = count * skeins_per_child @@ -3003,7 +3003,7 @@ def generate_38(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Martha", "Mary", "Elizabeth", "Susan", "Margaret", "Patricia"] clothing_items = ["sweater", "shawl", "hat", "cardigan", "poncho", "vest", "beanie", "tunic"] accessories = ["mittens", "booties", "socks", "leg warmers", "gloves"] @@ -3037,11 +3037,11 @@ def generate_38(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_39(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_39(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( total: int, grade: str, school_name: str, num_girls: int, day: str, absent_girls: int, absent_boys: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: num_boys = total - num_girls remaining_boys = num_boys - absent_boys @@ -3067,7 +3067,7 @@ def generate_39(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: school_names = ["Maple Grove", "Sunny Hill", "Oak Ridge", "Pine Valley"] grades = ["first", "second", "third", "fourth", "fifth"] days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] @@ -3112,9 +3112,9 @@ def generate_39(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_40(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_40(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(item: str, n1: int, c1: str, c2: str, c3: str, p: int) -> Dict[str, Any]: + def generate_from_variables(item: str, n1: int, c1: str, c2: str, c3: str, p: int) -> dict[str, Any]: more_cards = int(p / 100 * n1) n2 = n1 + more_cards n3 = n1 + n2 @@ -3147,7 +3147,7 @@ def generate_40(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: items = ["magician", "artist", "chef", "scientist", "athlete"] colors = ["red", "blue", "green", "yellow", "purple", "orange"] @@ -3186,11 +3186,11 @@ def generate_40(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_41(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_41(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, event: str, organization: str, fraction: str, current: int, total: int, currency: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: fraction = convert_fraction_word(fraction) fraction_val = Fraction(fraction) org_amount = int(total * fraction_val) @@ -3230,7 +3230,7 @@ def generate_41(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: } return FRACTION_WORDS.get(fraction_str.lower(), fraction_str) - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "William", "Robert", "Joseph"] events = ["field trip", "sports tournament", "conference", "music festival", "science fair"] organizations = ["school", "community center", "local charity", "youth club", "parent association"] @@ -3287,7 +3287,7 @@ def generate_41(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_42(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_42(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( title: str, @@ -3299,7 +3299,7 @@ def generate_42(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: fee2_name: str, fee2_percent: int, loan: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: fee1_amount = price * fee1_percent // 100 fee2_amount = price * fee2_percent // 100 @@ -3337,7 +3337,7 @@ def generate_42(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: titles = ["Mr.", "Prof.", "Dr."] names = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"] properties = ["house", "apartment", "condo", "villa", "cottage"] @@ -3399,9 +3399,9 @@ def generate_42(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_43(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_43(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(person1: str, item: str, n: int, relation: str, k: int) -> Dict[str, Any]: + def generate_from_variables(person1: str, item: str, n: int, relation: str, k: int) -> dict[str, Any]: other_amount = n - k total = n + other_amount @@ -3425,7 +3425,7 @@ def generate_43(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: people = ["student", "boy", "child", "kid"] items = ["marble", "sticker", "toy", "book", "pencil"] relations = ["sister", "brother", "friend", "cousin"] @@ -3453,7 +3453,7 @@ def generate_43(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_44(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_44(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( store: str, @@ -3467,7 +3467,7 @@ def generate_44(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: p2: int, p3: int, currency: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total1 = n1 * p1 total2 = n2 * p2 total3 = n3 * p3 @@ -3493,7 +3493,7 @@ def generate_44(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: stores = ["store", "shop", "market", "warehouse"] colors = ["red", "blue", "green", "yellow", "purple", "orange", "pink"] currencies = ["$", "€", "£"] @@ -3526,11 +3526,11 @@ def generate_44(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_45(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_45(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, event: str, food: str, obj: str, package_husband: int, used_items: int, total_remaining: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_items = total_remaining + used_items package_size = total_items - package_husband @@ -3557,7 +3557,7 @@ def generate_45(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Emma", "Olivia", "Sophia", "Isabella", "Ava", "Mia", "Charlotte"] events = ["lunch party", "birthday party", "potluck party", "baby shower", "game night"] foods = [ @@ -3609,11 +3609,11 @@ def generate_45(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_46(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_46(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( fruit1: str, fruit2: str, n1: int, n2: int, frac1: float, frac2: float, spill: int, total: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n1_after_spill = n1 - spill water_fruit1 = n1_after_spill * frac1 water_fruit2 = n2 * frac2 @@ -3642,7 +3642,7 @@ def generate_46(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: fruits = ["apple", "grape", "mango", "peach", "lemon"] fractions = { "two-thirds": 2 / 3, @@ -3684,11 +3684,11 @@ def generate_46(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_47(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_47(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, n1: int, c1: float, n2: int, c2: float, c3: int, obj1: str, obj2: str, currency: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: cost1 = n1 * c1 cost2 = n2 * c2 total_cost = cost1 + cost2 + c3 @@ -3720,7 +3720,7 @@ def generate_47(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "William", "Robert", "Thomas"] items = ["notebooks", "pencils", "erasers", "crayons", "colored pencils", "markers", "rulers", "folders"] currencies = ["$", "€", "£"] @@ -3756,11 +3756,11 @@ def generate_47(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_48(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_48(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( item1: str, item2: str, shop: str, currency: str, price1: int, price2: int, n1: int, n2: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total1 = n1 * price1 total2 = n2 * price2 diff = total1 - total2 @@ -3793,7 +3793,7 @@ def generate_48(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: items1 = ["bread", "sourdough"] items2 = ["bagel", "muffin", "croissant", "biscuit"] shops = ["bakery", "cafe", "store", "market"] @@ -3830,11 +3830,11 @@ def generate_48(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_49(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_49(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, item1: str, item2: str, price1: int, price2: int, total: float, n1: int, percent: int, currency: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: spent = total * (100 - percent) / 100 # Amount spent cost_item1 = n1 * price1 / 100 # Cost of item1 spent_item2 = spent - cost_item1 # Amount spent on item2 @@ -3869,7 +3869,7 @@ def generate_49(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["George", "James", "John", "Robert", "Michael", "William"] items = ["pretzels", "popcorn", "gum", "cookies", "crackers"] currencies = ["$", "£", "€"] diff --git a/reasoning_gym/arithmetic/gsm_symbolic/generators_50_99.py b/reasoning_gym/arithmetic/gsm_symbolic/generators_50_99.py index d700c2f5..960e023a 100644 --- a/reasoning_gym/arithmetic/gsm_symbolic/generators_50_99.py +++ b/reasoning_gym/arithmetic/gsm_symbolic/generators_50_99.py @@ -5,9 +5,9 @@ from typing import Any, Dict from reasoning_gym.utils import format_number, is_integer -def generate_50(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_50(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, pieces1: int, pieces2: int) -> Dict[str, Any]: + def generate_from_variables(name: str, pieces1: int, pieces2: int) -> dict[str, Any]: half_pieces1 = pieces1 // 2 total_pieces = half_pieces1 + pieces2 @@ -29,7 +29,7 @@ def generate_50(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Teddy", "Tommy", "Billy", "Jimmy", "Bobby", "Danny"] name = rng.choice(names) @@ -53,7 +53,7 @@ def generate_50(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_51(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_51(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -67,7 +67,7 @@ def generate_51(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: tokens: int, cost1: int, cost2: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: cost_per_ride = cost2 * times cost_per_person = tokens + cost1 + cost_per_ride @@ -107,7 +107,7 @@ def generate_51(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Sophia", "Isabella", "Mia", "Charlotte"] parents = ["mom", "dad", "aunt", "uncle"] activities1 = ["mini-golf", "bowling", "laser tag"] @@ -151,9 +151,9 @@ def generate_51(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_52(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_52(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, alphabets: tuple, n1: str, frac: str) -> Dict[str, Any]: + def generate_from_variables(name: str, alphabets: tuple, n1: str, frac: str) -> dict[str, Any]: alphabet_name, alphabet_count = alphabets # Calculate intermediate values @@ -189,7 +189,7 @@ def generate_52(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Sophia", "Olivia", "Ava", "Isabella", "Mia", "Charlotte", "Amelia"] alphabets = [ ("alphabet", 26), @@ -229,9 +229,9 @@ def generate_52(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_53(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_53(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, sides: int, target: int, property: str) -> Dict[str, Any]: + def generate_from_variables(name: str, sides: int, target: int, property: str) -> dict[str, Any]: numbers_above = sides - target prob_above = (numbers_above / sides) * 100 prob_two_in_row = 25 # probability of two even/odd in a row is always 25% @@ -257,7 +257,7 @@ def generate_53(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph"] properties = ["even", "odd"] @@ -290,7 +290,7 @@ def generate_53(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_54(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_54(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, @@ -301,7 +301,7 @@ def generate_54(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: location1: str, location2: str, location3: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: time_after_library = total_time - library_time remaining_time = time_after_library - station_time @@ -328,7 +328,7 @@ def generate_54(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Jack", "James", "William", "Michael", "David", "Joseph"] locations = ["cinema", "mall", "library", "park", "gym", "bank", "school"] @@ -366,11 +366,11 @@ def generate_54(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_55(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_55(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, place: str, fruit: str, location: str, insect1: str, insect2: str, n: int, frac: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: num_insect1 = int(n * 0.5) # half as many bugs as ants total_insects = n + num_insect1 @@ -396,7 +396,7 @@ def generate_55(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Dax", "Alex", "Sam", "Jordan", "Taylor", "Morgan", "Riley"] places = ["orchard", "backyard", "greenhouse", "allotment"] fruits = ["strawberries", "cherries", "blueberries", "raspberries"] @@ -430,11 +430,11 @@ def generate_55(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_56(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_56(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( family: str, item: str, total: int, n1: int, n2: int, flavor1: str, flavor2: str, flavor3: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n3 = total - (n1 + n2) question = f"The {family} family is busy making {item}s. So far, they've made {total} {item}s. They have {n1} {flavor1} {item}s, {n2} {flavor2} {item}s, and some {flavor3} {item}s. How many {flavor3} {item}s have they made?" @@ -459,7 +459,7 @@ def generate_56(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: families = ["Smith", "Johnson", "Williams", "Brown", "Jones"] items = ["cupcake", "muffin", "brownie", "biscuit"] flavors = ["vanilla", "strawberry", "blueberry", "lemon", "peanut butter"] @@ -492,11 +492,11 @@ def generate_56(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_57(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_57(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( n1: int, sport1: str, sport2: str, sport3: str, n2: int, n3: int, multiplier: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n_volleyball = n1 * multiplier n_soccer = n2 + n3 total = n1 + n_volleyball + n_soccer @@ -521,7 +521,7 @@ def generate_57(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: sports = ["basketball", "badminton", "table tennis", "football", "volleyball"] sport1, sport2, sport3 = rng.sample(sports, 3) @@ -567,11 +567,11 @@ def generate_57(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_58(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_58(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, container: str, liquid: str, volume: int, unit: str, num_containers: int, calories: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_volume = volume * num_containers total_calories = total_volume * calories @@ -597,7 +597,7 @@ def generate_58(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Mike", "James", "David", "Robert", "William"] containers = ["cup", "bottle", "carton"] liquids = ["juice", "soda", "sparkling water", "tea", "lemonade"] @@ -628,11 +628,11 @@ def generate_58(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_59(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_59(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( time_per_interval: int, distance_per_interval: int, total_distance: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: intervals = total_distance // distance_per_interval total_time = intervals * time_per_interval @@ -653,7 +653,7 @@ def generate_59(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: # Start with total_distance limit and work backwards max_total_distance = 100 @@ -698,11 +698,11 @@ def generate_59(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_60(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_60(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, unit: str, total_dist: int, beach_dist: int, sidewalk_dist: int, speed_mult: int, beach_time: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: beach_rate = Fraction(beach_dist, beach_time) sidewalk_rate = beach_rate * speed_mult @@ -730,7 +730,7 @@ def generate_60(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Emma", "Sophia", "Isabella", "Olivia", "Ava", "Mia", "Emily"] units = ["mile", "kilometer", "block"] @@ -783,7 +783,7 @@ def generate_60(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_61(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_61(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -804,7 +804,7 @@ def generate_61(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: p2: float, p3: float, discount: float, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: # Calculate costs item1_cost = n1 * p1 + n2 * (1 - discount) * p1 + k * p1 # Cost of item1 with discount applied @@ -845,7 +845,7 @@ def generate_61(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte"] locations = ["beach", "boardwalk", "pier", "coast"] shops = ["souvenir store", "gift shop", "beach shop", "seaside store"] @@ -939,11 +939,11 @@ def generate_61(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_62(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_62(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( item: str, num_slices: int, name1: str, name2: str, slices_per_day: int, multiplier: int, unit: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: second_person_slices = slices_per_day * multiplier total_daily_slices = slices_per_day + second_person_slices @@ -971,7 +971,7 @@ def generate_62(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: items = ["pizza", "cake", "pie", "lasagna"] units = ["pieces", "portions", "servings"] names = ["Emma", "Liam", "Olivia", "Noah", "Ava", "Elijah", "Charlotte", "James"] @@ -1004,9 +1004,9 @@ def generate_62(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_63(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_63(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, hours: int, days: int, rate: int, bonus: int, month: str) -> Dict[str, Any]: + def generate_from_variables(name: str, hours: int, days: int, rate: int, bonus: int, month: str) -> dict[str, Any]: daily_pay = hours * rate monthly_days = days * 4 monthly_base = daily_pay * monthly_days @@ -1041,7 +1041,7 @@ def generate_63(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph"] months = [ "January", @@ -1086,9 +1086,9 @@ def generate_63(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_64(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_64(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, n1: int, d1: int, n2: int, d2: int) -> Dict[str, Any]: + def generate_from_variables(name: str, n1: int, d1: int, n2: int, d2: int) -> dict[str, Any]: first_period = n1 * d1 second_period = n2 * d2 total_eggs = first_period + second_period @@ -1120,7 +1120,7 @@ def generate_64(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Chester", "James", "John", "Robert", "Michael", "William", "David"] name = rng.choice(names) @@ -1154,11 +1154,11 @@ def generate_64(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_65(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_65(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, fish: str, day: str, w1: int, w2: int, w3: int, n: int, unit: str, cur: str, price: float - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total = int((w1 + w2) * price + (n - 2) * w3 * price) question = f"{name} caught {n} {fish}s last {day}, the first {fish} he caught weighs {w1} {unit}s, the second {fish} he caught weighs {w2} {unit}s, and the last {fish} he caught weighs {w3} {unit}s. If a {unit} of {fish} costs {cur}{price:.2f}, how much will he earn after selling all the {fish}s to the market?" @@ -1189,7 +1189,7 @@ def generate_65(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "Robert", "William", "Richard"] fish = ["salmon", "cod", "trout", "steelhead"] days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] @@ -1228,7 +1228,7 @@ def generate_65(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_66(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_66(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -1240,7 +1240,7 @@ def generate_66(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: min2: int, total_hours: int, num_wed_episodes: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: mon, tue, wed, thu, fri = weekdays @@ -1274,7 +1274,7 @@ def generate_66(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph"] weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] @@ -1312,11 +1312,11 @@ def generate_66(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_67(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_67(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, fruit: str, n1: int, n2: int, d1: str, d2: str, d3: str, mult: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: first_two_days = n1 + n2 friday_amount = mult * n1 total = first_two_days + friday_amount @@ -1344,7 +1344,7 @@ def generate_67(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "James", "William", "Michael", "David", "Robert", "Thomas"] fruits = ["banana", "apple", "orange", "pear", "peach", "plum"] weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] @@ -1376,9 +1376,9 @@ def generate_67(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_68(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_68(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(n0: int, r: int, d: int, disease: str) -> Dict[str, Any]: + def generate_from_variables(n0: int, r: int, d: int, disease: str) -> dict[str, Any]: # Calculate infected people after each day day1_new = n0 * r day1_total = n0 + day1_new @@ -1408,7 +1408,7 @@ def generate_68(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: "variables": {"initial_infected": n0, "infection_rate": r, "days": d, "disease_type": disease}, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: diseases = ["virus", "bacteria", "parasite", "infection"] disease = rng.choice(diseases) d = 3 # Fixed at 3 days @@ -1451,9 +1451,9 @@ def generate_68(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_69(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_69(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, document: str, total_pages: int, fraction: str) -> Dict[str, Any]: + def generate_from_variables(name: str, document: str, total_pages: int, fraction: str) -> dict[str, Any]: frac_num = eval(fraction) pages_done = int(total_pages * frac_num) pages_remaining = total_pages - pages_done @@ -1477,7 +1477,7 @@ def generate_69(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Amelia", "Harper", "Evelyn"] documents = ["essay", "report", "thesis", "dissertation", "assignment"] fractions = ["1/2", "1/3", "1/4", "2/3", "3/4"] @@ -1507,11 +1507,11 @@ def generate_69(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_70(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_70(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, objects: str, n: int, obstacle: str, frac: float, k: int, fake_num: int, fake_object: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: dropped = int(n * frac) remaining = n - dropped @@ -1548,7 +1548,7 @@ def generate_70(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph"] objects = ["marbles", "coins", "buttons", "beads", "pebbles"] obstacles = ["rock", "stick", "toy", "root"] @@ -1609,7 +1609,7 @@ def generate_70(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_71(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_71(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -1624,7 +1624,7 @@ def generate_71(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: p1: int, p2: int, p3: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: cost1 = n1 * p1 cost2 = n2 * p2 cost3 = n3 * p3 @@ -1658,7 +1658,7 @@ def generate_71(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_female = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Charlotte", "Mia", "Amelia"] shops = ["bakery", "patisserie", "confectionery", "cafe"] items = ["pastries", "baked goods", "desserts", "treats"] @@ -1697,11 +1697,11 @@ def generate_71(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_72(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_72(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( structure: str, n1: int, color1: str, color2: str, color3: str, obj: str, mult: int, total: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n2 = n1 * mult n3 = total - n1 - n2 @@ -1728,7 +1728,7 @@ def generate_72(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: structures = ["building", "pyramid", "stack", "tower"] objects = ["brick", "cube", "tile", "block"] colors = ["green", "purple", "orange", "pink", "white", "black"] @@ -1761,7 +1761,7 @@ def generate_72(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_73(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_73(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -1776,7 +1776,7 @@ def generate_73(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: cn: int, cm: int, currency: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: gingerbread_sunday = n1 + n2 total_gingerbread = n1 + gingerbread_sunday @@ -1814,7 +1814,7 @@ def generate_73(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "William", "Robert"] fruits = ["apple", "cherry", "blueberry", "peach"] foods = ["cookie", "brownie", "muffin", "cupcake"] @@ -1850,11 +1850,11 @@ def generate_73(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_74(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_74(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, big_fish: str, length: int, num_remoras: int, remora_length: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_remora_length_inches = num_remoras * remora_length total_remora_length_feet = total_remora_length_inches / 12 percentage = int((total_remora_length_feet / length) * 100) @@ -1880,7 +1880,7 @@ def generate_74(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Benny", "Tommy", "Jimmy", "Billy", "Johnny", "Bobby"] big_fish = ["dolphin", "whale", "shark"] @@ -1949,11 +1949,11 @@ def generate_74(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_75(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_75(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, name2: str, color1: str, color2: str, n1: int, n2: int, frac1: float, mult1: float - ) -> Dict[str, Any]: + ) -> dict[str, Any]: n1_result = int(n1 * frac1) n2_result = int(n2 * mult1) @@ -1987,7 +1987,7 @@ def generate_75(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Ben", "James", "John", "Michael", "William", "David", "Richard", "Joseph"] colors = ["blue", "red", "green", "yellow", "purple", "orange"] @@ -2016,9 +2016,9 @@ def generate_75(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_76(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_76(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(n: int, p1: int, p2: int, company: str, frac: float) -> Dict[str, Any]: + def generate_from_variables(n: int, p1: int, p2: int, company: str, frac: float) -> dict[str, Any]: interviews = int(n * (p1 / 100)) offers = int(interviews * (p2 / 100)) accepts = int(offers * frac) @@ -2049,7 +2049,7 @@ def generate_76(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: companies = ["Microsoft", "Apple", "Amazon", "Facebook", "Netflix", "Tesla", "Google"] fractions = {"a third": 1 / 3, "half": 1 / 2, "a quarter": 1 / 4, "two thirds": 2 / 3} @@ -2099,11 +2099,11 @@ def generate_76(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_77(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_77(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( event: str, m: int, w: int, t: str, frac: float, m_left: int, group1: str, group2: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total = m + w left_count = int(total * frac) stayed = total - left_count @@ -2137,7 +2137,7 @@ def generate_77(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: events = ["party", "meeting", "conference", "gathering", "celebration"] groups = ["teachers", "doctors", "engineers", "nurses", "artists", "lawyers"] times = ["an hour", "two hours", "half an hour", "45 minutes"] @@ -2205,9 +2205,9 @@ def generate_77(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_78(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_78(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name1: str, name2: str, age_diff: int, age1: int) -> Dict[str, Any]: + def generate_from_variables(name1: str, name2: str, age_diff: int, age1: int) -> dict[str, Any]: age2 = age1 + age_diff avg_age = (age1 + age2) // 2 @@ -2235,7 +2235,7 @@ def generate_78(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Amelia"] name1, name2 = rng.sample(names, 2) @@ -2262,7 +2262,7 @@ def generate_78(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_79(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_79(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -2273,7 +2273,7 @@ def generate_79(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: currency: str, first_hour_cost: int, multiplier: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_hours = end_time - start_time paid_hours = total_hours - free_hours other_hours = paid_hours - 1 @@ -2314,7 +2314,7 @@ def generate_79(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard"] vehicles = ["limousine", "party bus", "boat", "luxury car"] currencies = ["$", "€", "£"] @@ -2357,11 +2357,11 @@ def generate_79(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_80(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_80(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, color1: str, color2: str, n1: int, n2: int, n3: int, n4: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: blue_spools = n1 + n2 total_spools = n1 + n2 + n3 + n4 percent_blue = int(100 * blue_spools / total_spools) @@ -2389,7 +2389,7 @@ def generate_80(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Candy", "Sarah", "Emma", "Olivia", "Isabella", "Sophia", "Mia", "Charlotte"] colors = ["blue", "red", "green", "yellow", "purple", "orange"] @@ -2424,11 +2424,11 @@ def generate_80(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_81(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_81(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( occupation: str, weeks_per_month: int, days_per_week: int, pay_per_day: int, currency: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: days_per_month = days_per_week * weeks_per_month monthly_pay = days_per_month * pay_per_day yearly_pay = monthly_pay * 12 @@ -2453,7 +2453,7 @@ def generate_81(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: occupations = ["plumber", "electrician", "painter", "carpenter", "landscaper"] currencies = ["$", "£", "€"] @@ -2480,9 +2480,9 @@ def generate_81(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_82(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_82(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name: str, num_emails: int, no_response_percent: int, workdays: int) -> Dict[str, Any]: + def generate_from_variables(name: str, num_emails: int, no_response_percent: int, workdays: int) -> dict[str, Any]: no_response = num_emails * no_response_percent // 100 responds_to = num_emails - no_response total_responses = responds_to * workdays @@ -2512,7 +2512,7 @@ def generate_82(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph"] name = rng.choice(names) @@ -2542,9 +2542,9 @@ def generate_82(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_83(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_83(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(name1: str, name2: str, total: int, diff: int, unit: str) -> Dict[str, Any]: + def generate_from_variables(name1: str, name2: str, total: int, diff: int, unit: str) -> dict[str, Any]: amount1 = (total - diff) // 2 # Sam's amount amount2 = amount1 + diff # Harry's amount @@ -2568,7 +2568,7 @@ def generate_83(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Sam", "Harry", "Tom", "John", "Mike", "Dave", "Steve", "Bob"] units = ["feet", "yards", "meters"] @@ -2607,11 +2607,11 @@ def generate_83(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_84(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_84(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, miles: str, time_cold: int, extra_time: int, multiplier: float, distance: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: time_warm = extra_time + multiplier * time_cold time_cold_total = distance * time_cold time_warm_total = distance * time_warm @@ -2646,7 +2646,7 @@ def generate_84(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Ray", "Jim", "Bob", "Tom", "Mike", "John", "Steve"] units = ["mile", "kilometer"] @@ -2695,11 +2695,11 @@ def generate_84(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_85(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_85(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, room_type: str, area: int, length: int, unit1: str, unit2: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: conversion = 3 if unit1 == "feet" and unit2 == "yards" else 1 length_converted = length * conversion width = area // length_converted @@ -2730,7 +2730,7 @@ def generate_85(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def calculate_max_width(difficulty: float, length: int, conversion: int) -> int: # Cap the maximum width to avoid numbers getting too large theoretical_max = int(100 * difficulty) @@ -2784,7 +2784,7 @@ def generate_85(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_86(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_86(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( animals: str, @@ -2802,7 +2802,7 @@ def generate_86(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: w3: int, w4: int, total: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: # Calculate weights sugar_weight = n4 * w4 carrot_weight = n3 * w3 @@ -2831,7 +2831,7 @@ def generate_86(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: animals = rng.choice(["horses", "cows", "sheep", "pigs", "alpacas"]) unit = rng.choice(["pound", "kilogram"]) feed_options = ["hay", "corn", "oats", "apples", "wheat"] @@ -2876,7 +2876,7 @@ def generate_86(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_87(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_87(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -2888,7 +2888,7 @@ def generate_87(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: num_medium: int, num_small: int, total_amount: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: large_used = num_large * weight_large medium_used = num_medium * weight_medium @@ -2926,7 +2926,7 @@ def generate_87(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Peter", "John", "Michael", "David", "James", "Robert", "William"] units = ["ounce", "gram", "milliliter"] @@ -2963,9 +2963,9 @@ def generate_87(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_88(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_88(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: - def generate_from_variables(school: str, venue: str, total: int, graduates: int, faculty: int) -> Dict[str, Any]: + def generate_from_variables(school: str, venue: str, total: int, graduates: int, faculty: int) -> dict[str, Any]: remaining_seats = total - (graduates + faculty) tickets_per_graduate = remaining_seats // graduates @@ -2989,7 +2989,7 @@ def generate_88(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: schools = ["Oakwood High School", "Riverside Academy", "Sunnyside High", "Greenville High School"] venues = ["Auditorium", "Gymnasium", "Sports Arena", "Convention Center"] @@ -3019,7 +3019,7 @@ def generate_88(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_89(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_89(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, @@ -3032,7 +3032,7 @@ def generate_89(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: multiplier: float, less_amount: int, fraction: float, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_eggs = num_dozen * 12 found_second = found_first * multiplier found_third = found_second - less_amount @@ -3072,7 +3072,7 @@ def generate_89(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = [ "Emma", "Liam", @@ -3135,11 +3135,11 @@ def generate_89(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_90(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_90(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( device: str, currency: str, rate1: float, rate2: float, threshold: int, total_mins: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: first_period = threshold second_period = total_mins - threshold @@ -3168,7 +3168,7 @@ def generate_90(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: devices = ["payphone", "phone booth", "hotel room phone"] currencies = ["$", "£", "€"] @@ -3211,11 +3211,11 @@ def generate_90(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_91(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_91(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, fruit: str, area: str, field_size: int, density: int, months: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: fruits_per_harvest = field_size * density harvests_per_year = 12 // months total_fruits = fruits_per_harvest * harvests_per_year @@ -3241,7 +3241,7 @@ def generate_91(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "Robert", "William", "Richard"] fruits = ["pineapple", "mango", "banana", "papaya", "coconut"] areas = ["hectare", "square yard", "square meter"] @@ -3270,7 +3270,7 @@ def generate_91(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_92(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_92(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -3287,7 +3287,7 @@ def generate_92(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: num3: int, unit: str, currency: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: round_p1 = round(price1) round_p2 = round(price2) @@ -3323,7 +3323,7 @@ def generate_92(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Mike", "David", "James", "Robert", "William", "Richard"] products = ["vegetable", "flower", "herb", "plant"] locations = ["local fair", "community market", "street bazaar", "town square"] @@ -3365,7 +3365,7 @@ def generate_92(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_93(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_93(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, @@ -3382,7 +3382,7 @@ def generate_93(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: frac1: float, mult1: int, frac2: float, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: kills_arthur = int(n1 * frac1) kills_walter = int(kills_arthur * mult1) @@ -3418,7 +3418,7 @@ def generate_93(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names_male = ["Arthur", "Bruce", "Charles", "David", "Edward", "Frederick", "George", "Henry"] creatures = ["ogres", "trolls", "goblins", "orcs", "giants"] weapons1 = ["sword", "mace", "battle axe", "war hammer"] @@ -3469,11 +3469,11 @@ def generate_93(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_94(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_94(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, num_shares: int, price_per_share: int, increase_pct: int, decrease_pct: int - ) -> Dict[str, Any]: + ) -> dict[str, Any]: initial_value = num_shares * price_per_share first_increase = initial_value * increase_pct / 100 value_after_increase = initial_value + first_increase @@ -3507,7 +3507,7 @@ def generate_94(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Maria", "Sarah", "Emma", "Isabella", "Sophia", "Mia", "Charlotte"] name = rng.choice(names) @@ -3542,11 +3542,11 @@ def generate_94(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_95(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_95(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name1: str, name2: str, relation: str, food: str, n1: int, n2: int, n3: int, time_unit: str, time_period: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: daily_total = n1 + n2 + n3 total = daily_total * (7 if time_period == "week" else 30) @@ -3573,7 +3573,7 @@ def generate_95(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: name1_options = ["A father", "A grandfather", "An uncle"] name2_options = ["his wife", "his partner", "his spouse"] relation_options = ["daughter", "son", "grandchild"] @@ -3607,11 +3607,11 @@ def generate_95(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_96(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_96(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, food: str, animal1: str, animal2: str, n1: int, n2: int, k1: int, k2: int, unit: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: animal2_amount = 2 * n1 - n2 # Amount per sheep animal2_total = k2 * animal2_amount # Total for sheep animal1_total = k1 * n1 # Total for goats @@ -3647,7 +3647,7 @@ def generate_96(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "Robert", "William", "Richard"] foods = ["hay", "grain", "feed", "silage"] animals = ["goat", "cow", "horse", "donkey", "llama", "alpaca", "pig", "turkey", "duck"] @@ -3685,11 +3685,11 @@ def generate_96(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_97(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_97(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, mult_run: int, frac_skip: float, skip_speed: int, total_time: int, frac_run: float, frac_walk: float - ) -> Dict[str, Any]: + ) -> dict[str, Any]: run_speed = skip_speed / frac_skip walk_speed = run_speed / mult_run walk_hours = total_time * frac_walk @@ -3728,7 +3728,7 @@ def generate_97(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["Dana", "Emma", "Sarah", "Julia", "Sophie", "Maria"] name = rng.choice(names) @@ -3781,7 +3781,7 @@ def generate_97(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_98(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_98(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, @@ -3794,7 +3794,7 @@ def generate_98(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: weight_passenger: int, unit: str, force_percent: int, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_passenger_weight = num_passengers * weight_passenger total_weight = weight_vehicle + weight_item + total_passenger_weight @@ -3824,7 +3824,7 @@ def generate_98(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["John", "Michael", "David", "James", "Robert", "William", "Richard"] vehicles = ["car", "van", "truck", "SUV"] items = ["luggage", "groceries", "equipment", "furniture"] @@ -3878,11 +3878,11 @@ def generate_98(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: return generate_example(rng, difficulty) -def generate_99(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: +def generate_99(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: def generate_from_variables( name: str, currency: str, initial_amount: float, quantity: int, item: str, store_type: str, unit_price: float - ) -> Dict[str, Any]: + ) -> dict[str, Any]: total_cost = quantity * unit_price remaining = initial_amount - total_cost @@ -3908,7 +3908,7 @@ def generate_99(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: }, } - def generate_example(rng: Random, difficulty: float = 1.0) -> Dict[str, Any]: + def generate_example(rng: Random, difficulty: float = 1.0) -> dict[str, Any]: names = ["David", "John", "Michael", "James", "William", "Robert"] currencies = ["$", "€", "£"] items = ["screw", "nail", "washer", "nut", "anchor"] diff --git a/reasoning_gym/arithmetic/lcm.py b/reasoning_gym/arithmetic/lcm.py index 19402fd9..893ed316 100644 --- a/reasoning_gym/arithmetic/lcm.py +++ b/reasoning_gym/arithmetic/lcm.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from functools import reduce from math import lcm from random import Random -from typing import List, Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -34,11 +34,11 @@ class LCMDataset(ProceduralDataset): def __init__(self, config: LCMConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _generate_numbers(self, rng: Random) -> Tuple[List[int], int]: + def _generate_numbers(self, rng: Random) -> tuple[list[int], int]: """Generate a list of random positive integers and their LCM. Will try up to 3 times to find numbers with LCM < product.""" - def calculate_product(nums: List[int]) -> int: + def calculate_product(nums: list[int]) -> int: return reduce(lambda x, y: x * y, nums) # Try up to 3 times to get LCM < product diff --git a/reasoning_gym/arithmetic/leg_counting.py b/reasoning_gym/arithmetic/leg_counting.py index e2278b1c..b8a15191 100644 --- a/reasoning_gym/arithmetic/leg_counting.py +++ b/reasoning_gym/arithmetic/leg_counting.py @@ -93,7 +93,7 @@ class LegCountingDataset(ProceduralDataset): def __init__(self, config: LegCountingConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _generate_animals(self, rng: Random) -> Dict[str, int]: + def _generate_animals(self, rng: Random) -> dict[str, int]: """Generate a random set of animals and their counts""" num_types = rng.randint(self.config.min_animals, self.config.max_animals) animals = {} diff --git a/reasoning_gym/arithmetic/number_format.py b/reasoning_gym/arithmetic/number_format.py index e03d2bdc..36e66c1d 100644 --- a/reasoning_gym/arithmetic/number_format.py +++ b/reasoning_gym/arithmetic/number_format.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -67,7 +67,7 @@ class NumberFormatDataset(ProceduralDataset): output.append(f"{candidate:.15e}") return output - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["metadata"]["solution"] if answer is not None and len(answer) > 0: diff --git a/reasoning_gym/arithmetic/power_function.py b/reasoning_gym/arithmetic/power_function.py index 24391a12..a4fb93c7 100644 --- a/reasoning_gym/arithmetic/power_function.py +++ b/reasoning_gym/arithmetic/power_function.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from math import pow from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -46,7 +46,7 @@ class PowerFunctionDataset(ProceduralDataset): def __init__(self, config: PowerFunctionConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["answer"] if answer is not None: diff --git a/reasoning_gym/arithmetic/prime_factorization.py b/reasoning_gym/arithmetic/prime_factorization.py index 55ec14ad..f6b03845 100644 --- a/reasoning_gym/arithmetic/prime_factorization.py +++ b/reasoning_gym/arithmetic/prime_factorization.py @@ -3,7 +3,7 @@ import math from dataclasses import dataclass from random import Random -from typing import Dict, List, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -29,7 +29,7 @@ class PrimeFactorizationDataset(ProceduralDataset): def __init__(self, config: PrimeFactorizationConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _prime_factors(self, n: int) -> List[int]: + def _prime_factors(self, n: int) -> list[int]: """Compute prime factors of a number""" factors = [] d = 2 @@ -44,11 +44,11 @@ class PrimeFactorizationDataset(ProceduralDataset): break return factors - def _normalize_answer(self, answer: str) -> List[int]: + def _normalize_answer(self, answer: str) -> list[int]: """Parse and sort factors from a string""" return sorted([int(factor.strip()) for factor in answer.split("×")]) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: oracle_answer = entry["answer"] reward = 0.0 if answer is not None: diff --git a/reasoning_gym/arithmetic/products.py b/reasoning_gym/arithmetic/products.py index 2d77035b..606e35eb 100644 --- a/reasoning_gym/arithmetic/products.py +++ b/reasoning_gym/arithmetic/products.py @@ -1,6 +1,6 @@ import random from dataclasses import dataclass -from typing import Dict, Optional +from typing import Any, Optional from reasoning_gym import utils @@ -102,7 +102,7 @@ class ProductsDataset(ProceduralDataset): expression = " ".join(expression_parts) return expression, result - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: oracle_answer = entry["answer"].strip() return utils.compute_reward(answer, oracle_answer) diff --git a/reasoning_gym/arithmetic/time_intervals.py b/reasoning_gym/arithmetic/time_intervals.py index f4011ba7..58e30cba 100644 --- a/reasoning_gym/arithmetic/time_intervals.py +++ b/reasoning_gym/arithmetic/time_intervals.py @@ -1,7 +1,7 @@ import random from dataclasses import dataclass, field from datetime import date, datetime, time, timedelta -from typing import List, Optional +from typing import Optional import pytz from dateutil import parser @@ -19,7 +19,7 @@ class TimeIntervalsConfig: min_date: date = date(1900, 1, 1) max_date: date = date(3000, 1, 1) max_date_difference_days: int = 100 - task_types: List[str] = field( + task_types: list[str] = field( default_factory=lambda: ["time", "time_seconds", "time_ms", "date", "datetime", "datetime_tz"] ) seed: Optional[int] = None diff --git a/reasoning_gym/coaching/base_curriculum.py b/reasoning_gym/coaching/base_curriculum.py index b3e97672..20684f75 100644 --- a/reasoning_gym/coaching/base_curriculum.py +++ b/reasoning_gym/coaching/base_curriculum.py @@ -11,7 +11,7 @@ class BaseCurriculum: self._attributes: dict[str, AttributeDefinition] = {} self._current_levels: dict[str, int] = {} - def generate_configuration(self, defaults: Optional[dict[str, any]] = None) -> ConfigT: + def generate_configuration(self, defaults: Optional[dict[str, Any]] = None) -> ConfigT: config_args = defaults.copy() if defaults is not None else {} for attr in self._attributes.values(): if isinstance(attr, RangeAttributeDefinition): diff --git a/reasoning_gym/coaching/coach.py b/reasoning_gym/coaching/coach.py index eeeab5d1..5142e666 100644 --- a/reasoning_gym/coaching/coach.py +++ b/reasoning_gym/coaching/coach.py @@ -6,7 +6,7 @@ from collections import OrderedDict from dataclasses import dataclass, field from pathlib import Path from statistics import mean, stdev -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Optional, Union from ..dataset import ProceduralDataset @@ -15,7 +15,7 @@ from ..dataset import ProceduralDataset class ScoreStats: """Container for score statistics with mean, std, min, max""" - scores: OrderedDict[Tuple[Tuple[str, Any], ...], Tuple[int, float, float, float, float]] + scores: OrderedDict[tuple[tuple[str, Any], ...], tuple[int, float, float, float, float]] def __str__(self) -> str: """Create a formatted report of the statistics @@ -41,7 +41,7 @@ class ScoreStats: class GroupedScores: """Container for grouped scores with total count""" - scores: OrderedDict[Tuple[Tuple[str, Any], ...], List[float]] + scores: OrderedDict[tuple[tuple[str, Any], ...], list[float]] total_scores: int def __str__(self) -> str: @@ -114,11 +114,11 @@ class GroupedScores: class ScoreBoard: """Tracks scores and metadata for coaching sessions""" - scores: List[float] = field(default_factory=list) - metadata: List[Dict[str, Any]] = field(default_factory=list) - conversations: List[Optional[List[Dict]]] = field(default_factory=list) + scores: list[float] = field(default_factory=list) + metadata: list[dict[str, Any]] = field(default_factory=list) + conversations: list[Optional[list[dict]]] = field(default_factory=list) - def add_score(self, score: float, metadata: Dict[str, Any], conversation: Optional[List[Dict]] = None) -> None: + def add_score(self, score: float, metadata: dict[str, Any], conversation: Optional[list[dict]] = None) -> None: """Add a new score entry with associated metadata and optional conversation Args: @@ -140,7 +140,7 @@ class ScoreBoard: """Return the number of stored scores""" return len(self.scores) - def _metadata_to_key(self, metadata: Dict[str, Any]) -> Tuple[Tuple[str, Any], ...]: + def _metadata_to_key(self, metadata: dict[str, Any]) -> tuple[tuple[str, Any], ...]: """Convert metadata dict to tuple of key-value pairs, sorted by key If source_dataset and source_index are present in metadata, they will be @@ -222,7 +222,7 @@ class Coach(ProceduralDataset): return self.dataset[idx] def score_answer( - self, answer: Optional[str], entry: Dict[str, Any], conversation: Optional[List[Dict]] = None + self, answer: Optional[str], entry: dict[str, Any], conversation: Optional[list[dict]] = None ) -> float: """Score answer and track results diff --git a/reasoning_gym/coaching/registry.py b/reasoning_gym/coaching/registry.py index 5d7fdd1a..076ea1cd 100644 --- a/reasoning_gym/coaching/registry.py +++ b/reasoning_gym/coaching/registry.py @@ -1,6 +1,6 @@ """Registry for managing active experiments.""" -from typing import Dict, List, Optional +from typing import Optional from ..composite import CompositeConfig from .experiment import Experiment @@ -25,7 +25,7 @@ class ExperimentRegistry: """Get an experiment by name.""" return self._experiments.get(name) - def list_experiments(self) -> List[str]: + def list_experiments(self) -> list[str]: """List all registered experiment names.""" return list(self._experiments.keys()) diff --git a/reasoning_gym/code/bf.py b/reasoning_gym/code/bf.py index e7def05e..3a7d9b0d 100644 --- a/reasoning_gym/code/bf.py +++ b/reasoning_gym/code/bf.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional import bfi @@ -108,14 +108,14 @@ int main() {{ # bf = Minify.minify(bf) # Is this necessary? return bf - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the BF task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/cognition/color_cube_rotation.py b/reasoning_gym/cognition/color_cube_rotation.py index 4b8dc30a..fe7feeea 100644 --- a/reasoning_gym/cognition/color_cube_rotation.py +++ b/reasoning_gym/cognition/color_cube_rotation.py @@ -1,7 +1,7 @@ import random from dataclasses import dataclass from enum import StrEnum -from typing import Dict, List, Optional, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -38,7 +38,7 @@ class Side(StrEnum): class Cube: """Represents a cube with colored sides""" - colors: Dict[Side, Color] + colors: dict[Side, Color] def rotate_front_to_top(self) -> None: """Rotate cube so front face becomes top""" @@ -162,7 +162,7 @@ class ColorCubeRotationDataset(ProceduralDataset): rotation_map[from_side]() def _generate_story( - self, initial_state: Dict[Side, Color], rotations: List[Side], target_side: Side, rng: random.Random + self, initial_state: dict[Side, Color], rotations: list[Side], target_side: Side, rng: random.Random ) -> str: """Generate story describing cube state and rotations""" # Describe initial state @@ -189,7 +189,7 @@ class ColorCubeRotationDataset(ProceduralDataset): return "\n".join(story_parts) - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: reward = 0.0 metadata = entry["metadata"] if answer is not None: diff --git a/reasoning_gym/cognition/figlet_fonts.py b/reasoning_gym/cognition/figlet_fonts.py index 7274a4ff..70f2e5e8 100644 --- a/reasoning_gym/cognition/figlet_fonts.py +++ b/reasoning_gym/cognition/figlet_fonts.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional import pyfiglet @@ -119,7 +119,7 @@ class FigletFontDataset(ProceduralDataset): "metadata": {"font": chosen_font, "space_letters": self.config.space_letters}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the figlet task. The function awards 1.0 for a correct answer and 0.1 points for each correct letter in the correct position, @@ -127,7 +127,7 @@ class FigletFontDataset(ProceduralDataset): Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/cognition/number_sequences.py b/reasoning_gym/cognition/number_sequences.py index bac6a18a..554989aa 100644 --- a/reasoning_gym/cognition/number_sequences.py +++ b/reasoning_gym/cognition/number_sequences.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from enum import StrEnum from random import Random -from typing import List, Optional +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -42,12 +42,12 @@ class NumberSequenceConfig: class PatternRule: """Represents a composable sequence pattern rule""" - def __init__(self, operations: List[Operation], parameters: List[int], subrules: List["PatternRule"] = None): + def __init__(self, operations: list[Operation], parameters: list[int], subrules: list["PatternRule"] = None): self.operations = operations self.parameters = parameters self.subrules = subrules or [] - def apply(self, sequence: List[int], position: int) -> int: + def apply(self, sequence: list[int], position: int) -> int: """Apply the rule to generate the next number""" result = sequence[position] # Start with current number @@ -75,7 +75,7 @@ class PatternRule: return result @classmethod - def compose(cls, rules: List["PatternRule"]) -> "PatternRule": + def compose(cls, rules: list["PatternRule"]) -> "PatternRule": """Create a new rule that composes multiple rules together""" return cls([Operation.COMPOSE], [0], subrules=rules) @@ -129,7 +129,7 @@ class PatternGenerator: return PatternRule(operations, parameters) - def is_interesting(self, sequence: List[int], max_value: int = 1000) -> bool: + def is_interesting(self, sequence: list[int], max_value: int = 1000) -> bool: """Check if sequence is interesting enough""" if not sequence: return False diff --git a/reasoning_gym/cognition/rectangle_count.py b/reasoning_gym/cognition/rectangle_count.py index 565df8db..5a86d467 100644 --- a/reasoning_gym/cognition/rectangle_count.py +++ b/reasoning_gym/cognition/rectangle_count.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -145,14 +145,14 @@ class RectangleCountDataset(ProceduralDataset): "metadata": {"puzzle": puzzle, "solution": answer}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the RectangleCount task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/cognition/rubiks_cube.py b/reasoning_gym/cognition/rubiks_cube.py index f504d92d..c34fd30a 100644 --- a/reasoning_gym/cognition/rubiks_cube.py +++ b/reasoning_gym/cognition/rubiks_cube.py @@ -1,7 +1,7 @@ import re from dataclasses import dataclass from random import Random -from typing import Dict, List, Optional +from typing import Any, Optional from magiccube.cube import Cube, CubeMove, CubeMoveType from magiccube.solver.basic.basic_solver import BasicSolver @@ -36,7 +36,7 @@ class RubiksCubeDataset(ProceduralDataset): ] super().__init__(config=config, seed=config.seed, size=config.size) - def _generate_random_moves(self, rng: Random, cube: Cube, num_steps: int = 50, wide=None) -> List[CubeMove]: + def _generate_random_moves(self, rng: Random, cube: Cube, num_steps: int = 50, wide=None) -> list[CubeMove]: """Generate a list of random moves (but don't apply them). By default scramble only uses wide moves to cubes with size >=4.""" @@ -106,7 +106,7 @@ class RubiksCubeDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the cube""" reward = 0.0 # default reward if answer is not None: diff --git a/reasoning_gym/composite.py b/reasoning_gym/composite.py index b30151fb..0e15bb0e 100644 --- a/reasoning_gym/composite.py +++ b/reasoning_gym/composite.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, replace from random import Random -from typing import Any, Dict, List, Optional +from typing import Any, Optional import yaml @@ -30,7 +30,7 @@ class CompositeConfig: size: int = 500 seed: Optional[int] = None - datasets: List[DatasetSpec] = None + datasets: list[DatasetSpec] = None def validate(self): """Validate configuration parameters""" @@ -120,7 +120,7 @@ class CompositeDataset(ProceduralDataset): return item - def update_dataset_config(self, dataset_name: str, config_updates: Dict[str, Any]) -> None: + def update_dataset_config(self, dataset_name: str, config_updates: dict[str, Any]) -> None: """Update configuration of a specific dataset Args: @@ -175,7 +175,7 @@ class CompositeDataset(ProceduralDataset): self.weights[i] = weight break - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Forward scoring to appropriate dataset""" dataset_name = entry["metadata"]["source_dataset"] return self.datasets[dataset_name].score_answer(answer, entry) diff --git a/reasoning_gym/dataset.py b/reasoning_gym/dataset.py index 7c929454..f4d263cd 100644 --- a/reasoning_gym/dataset.py +++ b/reasoning_gym/dataset.py @@ -4,10 +4,10 @@ from abc import ABC, abstractmethod from collections.abc import Iterable, Sized from copy import deepcopy from random import Random -from typing import Any, Dict, Iterator, Optional, Type, TypeVar +from typing import Any, Iterator, Optional, Type, TypeVar -class ProceduralDataset(ABC, Sized, Iterable[Dict[str, Any]]): +class ProceduralDataset(ABC, Sized, Iterable[dict[str, Any]]): """Abstract base class for procedural dataset generators""" def __init__(self, config: Any, seed: Optional[int] = None, size: int = 500): @@ -28,7 +28,7 @@ class ProceduralDataset(ABC, Sized, Iterable[Dict[str, Any]]): self._current_idx = 0 return self - def __next__(self) -> Dict[str, Any]: + def __next__(self) -> dict[str, Any]: """Get next item in iteration""" if self._current_idx >= self.size: raise StopIteration @@ -51,7 +51,7 @@ class ProceduralDataset(ABC, Sized, Iterable[Dict[str, Any]]): """ raise NotImplementedError - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Overwrite this method in derived classes if a single oracle answer is not available.""" oracle_answer = entry["answer"].strip() reward = 0.0 @@ -70,7 +70,7 @@ class ProceduralDataset(ABC, Sized, Iterable[Dict[str, Any]]): T = TypeVar("T", bound="ProceduralDataset") -class ReseedingDataset(Iterable[Dict[str, Any]]): +class ReseedingDataset(Iterable[dict[str, Any]]): """Wrapper that makes any ProceduralDataset infinite by reseeding when reaching the end""" def __init__(self, dataset: T, chunk_size: int = 500): @@ -100,14 +100,14 @@ class ReseedingDataset(Iterable[Dict[str, Any]]): # Create new dataset instance with chunk config return self.dataset_cls(new_config) - def __iter__(self) -> Iterator[Dict[str, Any]]: + def __iter__(self) -> Iterator[dict[str, Any]]: """Make the dataset iterable""" self._current_chunk = 0 self._current_dataset = self._create_chunk(0) self._current_idx = 0 return self - def __next__(self) -> Dict[str, Any]: + def __next__(self) -> dict[str, Any]: """Get next item, creating new chunk if needed""" if self._current_idx >= self.chunk_size: # Move to next chunk @@ -119,6 +119,6 @@ class ReseedingDataset(Iterable[Dict[str, Any]]): self._current_idx += 1 return item - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Forward scoring to the wrapped dataset's implementation""" return self.dataset.score_answer(answer, entry) diff --git a/reasoning_gym/factory.py b/reasoning_gym/factory.py index 8a9b8f5b..3f5a62b2 100644 --- a/reasoning_gym/factory.py +++ b/reasoning_gym/factory.py @@ -1,5 +1,5 @@ from dataclasses import is_dataclass -from typing import Dict, Type, TypeVar +from typing import Type, TypeVar from .dataset import ProceduralDataset @@ -8,7 +8,7 @@ ConfigT = TypeVar("ConfigT") DatasetT = TypeVar("DatasetT", bound=ProceduralDataset) # Global registry of datasets -DATASETS: Dict[str, tuple[Type[ProceduralDataset], Type]] = {} +DATASETS: dict[str, tuple[Type[ProceduralDataset], Type]] = {} def register_dataset(name: str, dataset_cls: Type[DatasetT], config_cls: Type[ConfigT]) -> None: diff --git a/reasoning_gym/games/countdown.py b/reasoning_gym/games/countdown.py index 19097259..88ad913d 100644 --- a/reasoning_gym/games/countdown.py +++ b/reasoning_gym/games/countdown.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional import sympy from sympy import Symbol, symbols @@ -89,7 +89,7 @@ class CountdownDataset(ProceduralDataset): }, } - def _generate_candidate_expression(self, rng: Random, num_terms: int) -> Tuple[sympy.Expr, List[int], List[Symbol]]: + def _generate_candidate_expression(self, rng: Random, num_terms: int) -> tuple[sympy.Expr, list[int], list[Symbol]]: """Generate a candidate expression with random numbers and operators Args: @@ -140,7 +140,7 @@ class CountdownDataset(ProceduralDataset): return expr, numbers, syms - def _generate_expression(self, rng: Random) -> Tuple[str, List[int], int]: + def _generate_expression(self, rng: Random) -> tuple[str, list[int], int]: """Generate a valid expression and its result Returns: @@ -171,7 +171,7 @@ class CountdownDataset(ProceduralDataset): raise ValueError(f"Failed to generate valid expression after {max_attempts} attempts") - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the problem""" reward = 0.0 metadata = entry["metadata"] diff --git a/reasoning_gym/games/futoshiki.py b/reasoning_gym/games/futoshiki.py index f71c6e2c..214ef550 100644 --- a/reasoning_gym/games/futoshiki.py +++ b/reasoning_gym/games/futoshiki.py @@ -4,7 +4,7 @@ import copy import itertools from dataclasses import dataclass from random import Random -from typing import Any, Dict, List, Optional, Set, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -85,7 +85,7 @@ class FutoshikiDataset(ProceduralDataset): } def _puzzle_to_string( - self, puzzle_grid: List[List[int]], constraints: Dict[Tuple[Tuple[int, int], Tuple[int, int]], str] + self, puzzle_grid: list[list[int]], constraints: dict[tuple[tuple[int, int], tuple[int, int]], str] ) -> str: """ Formats a Futoshiki puzzle grid as a string with constraints. @@ -161,9 +161,9 @@ class FutoshikiDataset(ProceduralDataset): def _solve_logical( self, - grid: List[List[int]], - constraints: Dict[Tuple[Tuple[int, int], Tuple[int, int]], str], - ) -> Tuple[List[List[int]], List[List[Set[int]]]]: + grid: list[list[int]], + constraints: dict[tuple[tuple[int, int], tuple[int, int]], str], + ) -> tuple[list[list[int]], list[list[set[int]]]]: """ Apply logical rules to progress solution. Returns current state if logical rules can't progress further. @@ -172,7 +172,7 @@ class FutoshikiDataset(ProceduralDataset): size, working_grid = len(grid), copy.deepcopy(grid) # Starting point all numbers are candidates for all unfilled squares - candidates: List[List[Set[int]]] = [ + candidates: list[list[set[int]]] = [ [set(range(1, len(grid) + 1)) if grid[r][c] == 0 else {grid[r][c]} for c in range(len(grid))] for r in range(len(grid)) ] @@ -214,7 +214,7 @@ class FutoshikiDataset(ProceduralDataset): # Eliminate candidates based on constraints # Based on currently filled values, eliminate candidates that violate constraints - def _eliminate_by_constraint(rc_less: Tuple[int, int], rc_greater: Tuple[int, int]) -> bool: + def _eliminate_by_constraint(rc_less: tuple[int, int], rc_greater: tuple[int, int]) -> bool: r_less, c_less = rc_less r_greater, c_greater = rc_greater progress = False @@ -399,9 +399,9 @@ class FutoshikiDataset(ProceduralDataset): def _solve( self, - grid: List[List[int]], - constraints: Dict[Tuple[Tuple[int, int], Tuple[int, int]], str], - ) -> List[List[int]] | None: + grid: list[list[int]], + constraints: dict[tuple[tuple[int, int], tuple[int, int]], str], + ) -> list[list[int]] | None: """ Backtracking Futoshiki solver. Used to verify generated puzzles. Applies logical rules first then backtracks to fill gaps. @@ -442,11 +442,11 @@ class FutoshikiDataset(ProceduralDataset): def _is_valid( self, - grid: List[List[int]], + grid: list[list[int]], row: int, col: int, val: int, - constraints: Dict[Tuple[Tuple[int, int], Tuple[int, int]], str], + constraints: dict[tuple[tuple[int, int], tuple[int, int]], str], ) -> bool: """Check row, col, and inequality constraints for placing val in grid[row][col].""" size = len(grid) @@ -482,7 +482,7 @@ class FutoshikiDataset(ProceduralDataset): grid[row][col] = original_val return True - def _generate_random_solution(self, size: int, rng: Random) -> List[List[int]]: + def _generate_random_solution(self, size: int, rng: Random) -> list[list[int]]: """ Generates a random valid completed Futoshiki solution with numbers 1..size. Ensures each row and column has unique numbers. @@ -514,8 +514,8 @@ class FutoshikiDataset(ProceduralDataset): raise ValueError("Could not generate a random solution.") def _generate_random_constraints( - self, solution: List[List[int]], difficulty: int, rng: Random - ) -> Dict[Tuple[Tuple[int, int], Tuple[int, int]], str]: + self, solution: list[list[int]], difficulty: int, rng: Random + ) -> dict[tuple[tuple[int, int], tuple[int, int]], str]: """ Randomly add inequality constraints that match the solution. We only add constraints for adjacent cells (horizontal or vertical). @@ -570,10 +570,10 @@ class FutoshikiDataset(ProceduralDataset): def _remove_clues( self, - grid: List[List[int]], - constraints: Dict[Tuple[Tuple[int, int], Tuple[int, int]], str], + grid: list[list[int]], + constraints: dict[tuple[tuple[int, int], tuple[int, int]], str], rng: Random, - ) -> List[List[int]]: + ) -> list[list[int]]: """ Remove clues from a full solution to try to maintain a unique-solution puzzle. We remove in random order until we reach our target, or can't without losing uniqueness. diff --git a/reasoning_gym/games/knight_swap.py b/reasoning_gym/games/knight_swap.py index 8e8c1167..1e0270f5 100644 --- a/reasoning_gym/games/knight_swap.py +++ b/reasoning_gym/games/knight_swap.py @@ -2,7 +2,7 @@ import collections import json from dataclasses import dataclass from random import Random -from typing import Dict, FrozenSet, List, Optional, Set, Tuple +from typing import FrozenSet, Optional from ..factory import ProceduralDataset, register_dataset @@ -81,7 +81,7 @@ class KnightSwapLogic: return {abs(a_col - b_col), abs(a_row - b_row)} == {1, 2} @staticmethod - def is_connected(graph: Dict[str, List[str]]) -> bool: + def is_connected(graph: dict[str, list[str]]) -> bool: """Check if a graph is connected (all nodes reachable from any starting node).""" if not graph: return True @@ -98,7 +98,7 @@ class KnightSwapLogic: return len(visited) == len(graph) @staticmethod - def generate_board(num_nodes: int, rng: Random, max_attempts: int = 1000) -> Dict[str, List[str]]: + def generate_board(num_nodes: int, rng: Random, max_attempts: int = 1000) -> dict[str, list[str]]: """Generate a random connected board where edges represent valid knight moves.""" candidates = ["A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3", "D1", "D2", "D3"] attempts = 0 @@ -120,8 +120,8 @@ class KnightSwapLogic: @staticmethod def solve_swap( - board: Dict[str, List[str]], pieces: Dict[str, str], start_turn: str = "w" - ) -> Optional[List[Tuple[str, str, str]]]: + board: dict[str, list[str]], pieces: dict[str, str], start_turn: str = "w" + ) -> Optional[list[tuple[str, str, str]]]: """Find a sequence of moves to swap white and black pieces positions.""" @dataclass(frozen=True) @@ -177,7 +177,7 @@ class KnightSwapDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) self.game_logic = KnightSwapLogic() - def _format_board(self, board: Dict[str, List[str]], pieces: Dict[str, str]) -> str: + def _format_board(self, board: dict[str, list[str]], pieces: dict[str, str]) -> str: """Format the board state as a string.""" positions = list(board.keys()) if not positions: @@ -206,13 +206,13 @@ class KnightSwapDataset(ProceduralDataset): return "\n".join(lines) - def _format_moves(self, moves: List[Tuple[str, str, str]]) -> str: + def _format_moves(self, moves: list[tuple[str, str, str]]) -> str: """Format the solution moves as a string.""" if not moves: return "No" return json.dumps([f"{color},{start},{end}" for color, start, end in moves]) - def __getitem__(self, idx: int) -> Dict: + def __getitem__(self, idx: int) -> dict: """Generate a single Knight Swap puzzle.""" rng = Random(self.seed + idx) @@ -303,7 +303,7 @@ class KnightSwapDataset(ProceduralDataset): raise ValueError(f"Failed to generate valid puzzle after trying {self.config.max_attempts} different boards") - def score_answer(self, answer: Optional[str], entry: Dict) -> float: + def score_answer(self, answer: Optional[str], entry: dict) -> float: """Score the user's solution for the Knight Swap puzzle. The answer should be either: diff --git a/reasoning_gym/games/mini_sudoku.py b/reasoning_gym/games/mini_sudoku.py index 3ca1277c..dbcc2ab0 100644 --- a/reasoning_gym/games/mini_sudoku.py +++ b/reasoning_gym/games/mini_sudoku.py @@ -3,7 +3,7 @@ import copy from dataclasses import dataclass from random import Random -from typing import Any, List, Optional, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -46,7 +46,7 @@ class MiniSudokuDataset(ProceduralDataset): self._current_idx += 1 return item - def _is_valid(self, board: List[List[int]], row: int, col: int, num: int) -> bool: + def _is_valid(self, board: list[list[int]], row: int, col: int, num: int) -> bool: """Check if number can be placed at position""" # Check row if num in board[row]: @@ -64,7 +64,7 @@ class MiniSudokuDataset(ProceduralDataset): return False return True - def _solve(self, board: List[List[int]]) -> bool: + def _solve(self, board: list[list[int]]) -> bool: """Solve mini sudoku using backtracking""" empty = self._find_empty(board) if not empty: @@ -79,7 +79,7 @@ class MiniSudokuDataset(ProceduralDataset): board[row][col] = 0 return False - def _find_empty(self, board: List[List[int]]) -> Optional[Tuple[int, int]]: + def _find_empty(self, board: list[list[int]]) -> Optional[tuple[int, int]]: """Find an empty cell""" for i in range(4): for j in range(4): @@ -87,7 +87,7 @@ class MiniSudokuDataset(ProceduralDataset): return (i, j) return None - def _generate_solved_board(self, rng: Random) -> List[List[int]]: + def _generate_solved_board(self, rng: Random) -> list[list[int]]: """Generate a complete solved mini sudoku board""" board = [[0] * 4 for _ in range(4)] @@ -115,10 +115,10 @@ class MiniSudokuDataset(ProceduralDataset): raise RuntimeError("Failed to generate valid mini sudoku board") - def _count_solutions(self, board: List[List[int]], limit: int = 2) -> int: + def _count_solutions(self, board: list[list[int]], limit: int = 2) -> int: """Count the number of solutions for a given board""" - def _count_solutions_helper(board: List[List[int]]) -> int: + def _count_solutions_helper(board: list[list[int]]) -> int: empty = self._find_empty(board) if not empty: return 1 @@ -136,7 +136,7 @@ class MiniSudokuDataset(ProceduralDataset): return _count_solutions_helper(board) - def _create_puzzle(self, solved_board: List[List[int]], num_empty: int, rng: Random) -> List[List[int]]: + def _create_puzzle(self, solved_board: list[list[int]], num_empty: int, rng: Random) -> list[list[int]]: """Create puzzle by removing numbers from solved board""" puzzle = [row[:] for row in solved_board] cells = [(i, j) for i in range(4) for j in range(4)] @@ -157,7 +157,7 @@ class MiniSudokuDataset(ProceduralDataset): return puzzle - def _board_to_string(self, board: List[List[int]]) -> str: + def _board_to_string(self, board: list[list[int]]) -> str: """Convert board to string representation""" return "\n".join(" ".join(str(x) if x != 0 else "_" for x in row) for row in board) diff --git a/reasoning_gym/games/n_queens.py b/reasoning_gym/games/n_queens.py index 7f85c0d7..61f6ea66 100644 --- a/reasoning_gym/games/n_queens.py +++ b/reasoning_gym/games/n_queens.py @@ -7,7 +7,7 @@ https://en.wikipedia.org/wiki/Eight_queens_puzzle from copy import deepcopy from dataclasses import dataclass from random import Random -from typing import Dict, List, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -65,7 +65,7 @@ class NQueensDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) self._solutions = self._get_all_solutions(config.n) - def _get_all_solutions(self, n: int) -> List[List[List[str]]]: + def _get_all_solutions(self, n: int) -> list[list[list[str]]]: """Get all solutions for the N Queens puzzle""" visited_cols = set() @@ -97,7 +97,7 @@ class NQueensDataset(ProceduralDataset): backtrack(0) return res - def _create_puzzle(self, solved_board: List[List[str]], num_removed: int, rng: Random) -> List[List[str]]: + def _create_puzzle(self, solved_board: list[list[str]], num_removed: int, rng: Random) -> list[list[str]]: """Create puzzle by removing queens from solved board""" puzzle = deepcopy(solved_board) queens = [(i, j) for i in range(len(puzzle)) for j in range(len(puzzle)) if puzzle[i][j] == "Q"] @@ -107,15 +107,15 @@ class NQueensDataset(ProceduralDataset): puzzle[x][y] = "_" return puzzle - def _board_to_string(self, board: List[List[str]]) -> str: + def _board_to_string(self, board: list[list[str]]) -> str: """Convert board to string representation""" return "\n".join(" ".join(x for x in row) for row in board) - def _string_to_board(self, board_str: str) -> List[List[str]]: + def _string_to_board(self, board_str: str) -> list[list[str]]: """Convert string representation to board""" return [list(row.split()) for row in board_str.strip().split("\n")] - def _is_tractable_solution(self, puzzle: List[List[str]], solution: List[List[str]]) -> bool: + def _is_tractable_solution(self, puzzle: list[list[str]], solution: list[list[str]]) -> bool: """Check if a solution is achievable from the starting state of the puzzle""" for r in range(len(puzzle)): for c in range(len(puzzle)): @@ -150,7 +150,7 @@ class NQueensDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: valid_solutions = entry["metadata"]["valid_answers"] if answer is not None: if answer in valid_solutions: diff --git a/reasoning_gym/games/rush_hour.py b/reasoning_gym/games/rush_hour.py index 0ffaf277..1ab9489a 100644 --- a/reasoning_gym/games/rush_hour.py +++ b/reasoning_gym/games/rush_hour.py @@ -6,7 +6,7 @@ https://www.michaelfogleman.com/rush/ import random import re from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Optional from ..data import get_data_file_path from ..factory import ProceduralDataset, register_dataset @@ -105,7 +105,7 @@ class RushHourDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) # Load and filter puzzles from data file - self.puzzles: List[Tuple[str, int]] = [] # (board_config, min_moves) + self.puzzles: list[tuple[str, int]] = [] # (board_config, min_moves) data_path = get_data_file_path("rush_18k.txt") with data_path.open() as f: diff --git a/reasoning_gym/games/sokoban.py b/reasoning_gym/games/sokoban.py index 124aaf48..1b12169c 100644 --- a/reasoning_gym/games/sokoban.py +++ b/reasoning_gym/games/sokoban.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional import numpy as np @@ -80,14 +80,14 @@ Here is your puzzle: "metadata": {"gamestr": gamestr, "difficulty": difficulty}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the Sokoban task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/games/sudoku.py b/reasoning_gym/games/sudoku.py index 5efe79e7..d80569f8 100644 --- a/reasoning_gym/games/sudoku.py +++ b/reasoning_gym/games/sudoku.py @@ -3,7 +3,7 @@ import copy from dataclasses import dataclass from random import Random -from typing import Any, List, Optional, Set, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -47,7 +47,7 @@ class SudokuDataset(ProceduralDataset): self._current_idx += 1 return item - def _is_valid(self, board: List[List[int]], row: int, col: int, num: int) -> bool: + def _is_valid(self, board: list[list[int]], row: int, col: int, num: int) -> bool: """Check if number can be placed at position""" # Check row if num in board[row]: @@ -65,7 +65,7 @@ class SudokuDataset(ProceduralDataset): return False return True - def _get_possible_values(self, board: List[List[int]], row: int, col: int) -> Set[int]: + def _get_possible_values(self, board: list[list[int]], row: int, col: int) -> set[int]: """Get all possible values for a cell.""" row_values = set(board[row]) col_values = set(board[i][col] for i in range(9)) @@ -80,7 +80,7 @@ class SudokuDataset(ProceduralDataset): used_values = row_values | col_values | box_values return set(range(1, 10)) - used_values - def _solve(self, board: List[List[int]]) -> bool: + def _solve(self, board: list[list[int]]) -> bool: """Solve sudoku using backtracking""" empty = self._find_empty(board) if not empty: @@ -94,7 +94,7 @@ class SudokuDataset(ProceduralDataset): board[row][col] = 0 return False - def _find_empty(self, board: List[List[int]]) -> Optional[Tuple[int, int]]: + def _find_empty(self, board: list[list[int]]) -> Optional[tuple[int, int]]: """Find an empty cell""" for i in range(9): for j in range(9): @@ -102,7 +102,7 @@ class SudokuDataset(ProceduralDataset): return (i, j) return None - def _generate_solved_board(self, rng: Random) -> List[List[int]]: + def _generate_solved_board(self, rng: Random) -> list[list[int]]: """Generate a complete solved sudoku board""" board = [[0] * 9 for _ in range(9)] @@ -120,10 +120,10 @@ class SudokuDataset(ProceduralDataset): self._solve(board) return board - def _count_solutions(self, board: List[List[int]], limit: int = 2) -> int: + def _count_solutions(self, board: list[list[int]], limit: int = 2) -> int: """Count the number of solutions for a given board""" - def _get_min_possibilities_cell(board: List[List[int]]) -> Optional[Tuple[int, int, Set[int]]]: + def _get_min_possibilities_cell(board: list[list[int]]) -> Optional[tuple[int, int, set[int]]]: """ Get the cell with the lowest number of possibilities. Returns None if the board is already solved. @@ -145,7 +145,7 @@ class SudokuDataset(ProceduralDataset): return (*min_cell, min_values) if min_cell else None - def _count_solutions_helper(board: List[List[int]]) -> int: + def _count_solutions_helper(board: list[list[int]]) -> int: cell_info = _get_min_possibilities_cell(board) if not cell_info: return 1 @@ -162,7 +162,7 @@ class SudokuDataset(ProceduralDataset): return _count_solutions_helper(board) - def _create_puzzle(self, solved_board: List[List[int]], num_empty: int, rng: Random) -> List[List[int]]: + def _create_puzzle(self, solved_board: list[list[int]], num_empty: int, rng: Random) -> list[list[int]]: """Create puzzle by removing numbers from solved board""" puzzle = [row[:] for row in solved_board] cells = [(i, j) for i in range(9) for j in range(9)] @@ -183,7 +183,7 @@ class SudokuDataset(ProceduralDataset): return puzzle - def _board_to_string(self, board: List[List[int]]) -> str: + def _board_to_string(self, board: list[list[int]]) -> str: """Convert board to string representation""" return "\n".join(" ".join(str(x) if x != 0 else "_" for x in row) for row in board) diff --git a/reasoning_gym/games/tower_of_hanoi.py b/reasoning_gym/games/tower_of_hanoi.py index 1a868251..47afbb05 100644 --- a/reasoning_gym/games/tower_of_hanoi.py +++ b/reasoning_gym/games/tower_of_hanoi.py @@ -4,7 +4,7 @@ import math import random import re from dataclasses import dataclass -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -62,23 +62,23 @@ class MoveGenerator: It maintains the current state of all pegs to ensure move validity. """ - def __init__(self, num_disks: int, pegs: List[int], start: int, target: int): + def __init__(self, num_disks: int, pegs: list[int], start: int, target: int): self.num_disks = num_disks self.pegs = pegs self.start = start self.target = target self.auxiliary_pegs = [peg for peg in pegs if peg not in (start, target)] - self.pegs_state: Dict[int, List[int]] = {peg: [] for peg in pegs} + self.pegs_state: dict[int, list[int]] = {peg: [] for peg in pegs} for disk in range(num_disks, 0, -1): # Largest disk at the bottom self.pegs_state[start].append(disk) - self.moves: List[str] = [] - self.memo: Dict[Tuple[int, int], int] = {} # Memoization for T(n, k) + self.moves: list[str] = [] + self.memo: dict[tuple[int, int], int] = {} # Memoization for T(n, k) - def generate_moves(self) -> List[str]: + def generate_moves(self) -> list[str]: self.move(n=self.num_disks, source=self.start, target=self.target, auxiliary_pegs=self.auxiliary_pegs) return self.moves - def move(self, n: int, source: int, target: int, auxiliary_pegs: List[int]): + def move(self, n: int, source: int, target: int, auxiliary_pegs: list[int]): if n == 0: return if n == 1: @@ -175,10 +175,10 @@ class HanoiDataset(ProceduralDataset): Returns: dict with: - "question": Text describing the problem setup. - - "answer": List of moves to solve the puzzle. + - "answer": list of moves to solve the puzzle. - "metadata": Configuration and solution details. - "initial_state": (Optional) ASCII visualization of the initial pegs. - - "states": (Optional) List of ASCII visualizations after each move. + - "states": (Optional) list of ASCII visualizations after each move. """ rng = random.Random(self.seed + idx if self.seed is not None else None) @@ -282,11 +282,11 @@ class HanoiDataset(ProceduralDataset): if self.visualize: result["initial_state"] = initial_state_str - result["states"] = states # List of all states including initial and after each move + result["states"] = states # list of all states including initial and after each move return result - def _visualize_state(self, pegs_state: Dict[int, List[int]]) -> str: + def _visualize_state(self, pegs_state: dict[int, list[int]]) -> str: """ Create an ASCII visualization of the current state of the pegs. Adapts to variable number of pegs. @@ -321,7 +321,7 @@ class HanoiDataset(ProceduralDataset): return visualization - def _validate_move(self, pegs_state: Dict[int, List[int]], move: str) -> bool: + def _validate_move(self, pegs_state: dict[int, list[int]], move: str) -> bool: """ Validate that a move adheres to the Tower of Hanoi rules. @@ -356,7 +356,7 @@ class HanoiDataset(ProceduralDataset): print(f"Error validating move '{move}': {e}") return False - def _parse_move(self, move: str) -> Tuple[int, int, int]: + def _parse_move(self, move: str) -> tuple[int, int, int]: """ Parse a move string and extract disk number, from peg, and to peg. @@ -376,7 +376,7 @@ class HanoiDataset(ProceduralDataset): to_peg = int(match.group(3)) return disk, from_peg, to_peg - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """ Score the user's solution for the Tower of Hanoi puzzle. diff --git a/reasoning_gym/games/tsumego.py b/reasoning_gym/games/tsumego.py index f979a1e4..5da5b074 100644 --- a/reasoning_gym/games/tsumego.py +++ b/reasoning_gym/games/tsumego.py @@ -19,7 +19,7 @@ TODO: Generate multi-step Tsumego problems. import re from dataclasses import dataclass from random import Random -from typing import Any, Dict, List, Optional, Set, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -62,11 +62,11 @@ class TsumegoDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) # New helper method for board copying - def _copy_board(self, board: List[List[str]]) -> List[List[str]]: + def _copy_board(self, board: list[list[str]]) -> list[list[str]]: """Return a deep copy of the board.""" return [row[:] for row in board] - def _get_liberties(self, board: List[List[str]], row: int, col: int) -> Set[Tuple[int, int]]: + def _get_liberties(self, board: list[list[str]], row: int, col: int) -> set[tuple[int, int]]: """Get empty adjacent points (liberties) for a stone""" size = len(board) liberties = set() @@ -76,7 +76,7 @@ class TsumegoDataset(ProceduralDataset): liberties.add((r, c)) return liberties - def _get_group(self, board: List[List[str]], row: int, col: int) -> Set[Tuple[int, int]]: + def _get_group(self, board: list[list[str]], row: int, col: int) -> set[tuple[int, int]]: """Get all stones in the same group (connected stones of same color)""" size = len(board) color = board[row][col] @@ -94,14 +94,14 @@ class TsumegoDataset(ProceduralDataset): queue.append((nr, nc)) return group - def _count_liberties(self, board: List[List[str]], group: Set[Tuple[int, int]]) -> int: + def _count_liberties(self, board: list[list[str]], group: set[tuple[int, int]]) -> int: """Count total liberties for a group of stones""" liberties = set() for row, col in group: liberties.update(self._get_liberties(board, row, col)) return len(liberties) - def _would_capture(self, board: List[List[str]], row: int, col: int, color: str) -> bool: + def _would_capture(self, board: list[list[str]], row: int, col: int, color: str) -> bool: """Check if a move would capture any opponent stones""" size = len(board) opponent = "O" if color == "X" else "X" @@ -120,7 +120,7 @@ class TsumegoDataset(ProceduralDataset): return True return False - def _is_valid_move(self, board: List[List[str]], row: int, col: int, color: str) -> bool: + def _is_valid_move(self, board: list[list[str]], row: int, col: int, color: str) -> bool: """Check if a move is legal (not suicide, unless it captures)""" size = len(board) if not (0 <= row < size and 0 <= col < size): @@ -139,7 +139,7 @@ class TsumegoDataset(ProceduralDataset): group = self._get_group(board_copy, row, col) return self._count_liberties(board_copy, group) > 0 - def _make_move(self, board: List[List[str]], row: int, col: int, color: str) -> bool: + def _make_move(self, board: list[list[str]], row: int, col: int, color: str) -> bool: """Make a move and update ko point. Returns True if move was valid.""" if not self._is_valid_move(board, row, col, color): return False @@ -164,7 +164,7 @@ class TsumegoDataset(ProceduralDataset): return True - def _generate_capture_problem(self, size: int, rng: Random) -> Tuple[List[List[str]], Tuple[int, int]]: + def _generate_capture_problem(self, size: int, rng: Random) -> tuple[list[list[str]], tuple[int, int]]: """Generate a capture problem""" board = [["." for _ in range(size)] for _ in range(size)] stones_placed = 0 @@ -235,7 +235,7 @@ class TsumegoDataset(ProceduralDataset): tries += 1 raise RuntimeError("Failed to generate a capture problem") - def _board_to_string(self, board: List[List[str]]) -> str: + def _board_to_string(self, board: list[list[str]]) -> str: """Convert board to string representation""" size = len(board) # Column labels @@ -272,7 +272,7 @@ class TsumegoDataset(ProceduralDataset): "metadata": {"difficulty": {"board_size": size}, "board": board, "solution": solution_str}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Score the answer against the solution""" if answer is None: return 0.0 diff --git a/reasoning_gym/geometry/advanced_geometry.py b/reasoning_gym/geometry/advanced_geometry.py index 6f64daf8..90c8b463 100644 --- a/reasoning_gym/geometry/advanced_geometry.py +++ b/reasoning_gym/geometry/advanced_geometry.py @@ -1,11 +1,10 @@ import random -import re from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional +from typing import Any, Optional import numpy as np import sympy -from sympy.geometry import Point, Segment, Triangle +from sympy.geometry import Point from ..factory import ProceduralDataset, register_dataset @@ -23,7 +22,7 @@ class AdvancedGeometryConfig: # Probability or list of tasks we want to generate # For demonstration, we have three categories: - task_types: List[str] = field( + task_types: list[str] = field( default_factory=lambda: [ "orthocenter", "incircle_radius", @@ -228,7 +227,7 @@ class AdvancedGeometryDataset(ProceduralDataset): } return question, answer_str, metadata - def score_answer(self, answer: str | None, entry: Dict[str, Any]) -> float: + def score_answer(self, answer: str | None, entry: dict[str, Any]) -> float: reward = 0.0 expected_answer = entry["answer"] metadata = entry["metadata"] diff --git a/reasoning_gym/graphs/course_schedule.py b/reasoning_gym/graphs/course_schedule.py index 75abe44e..15497cc9 100644 --- a/reasoning_gym/graphs/course_schedule.py +++ b/reasoning_gym/graphs/course_schedule.py @@ -8,7 +8,7 @@ https://leetcode.com/problems/course-schedule/description/ from collections import defaultdict from dataclasses import dataclass from random import Random -from typing import List, Optional +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -54,7 +54,7 @@ class CourseScheduleDataset(ProceduralDataset): def __init__(self, config: CourseScheduleConfig): super().__init__(config=config, seed=config.seed, size=config.size) - def _can_finish(self, num_courses: int, prerequisites: List[List[int]]) -> bool: + def _can_finish(self, num_courses: int, prerequisites: list[list[int]]) -> bool: adj = defaultdict(list) for course, prereq in prerequisites: adj[course].append(prereq) @@ -81,7 +81,7 @@ class CourseScheduleDataset(ProceduralDataset): return True - def _create_prerequisites(self, rng: Random, courses: List[int], solvable: bool) -> List[List[int]]: + def _create_prerequisites(self, rng: Random, courses: list[int], solvable: bool) -> list[list[int]]: """Create a list of prerequisites for each course""" prerequisites = [] # Generate a valid course schedule diff --git a/reasoning_gym/graphs/family_relationships.py b/reasoning_gym/graphs/family_relationships.py index d875d7a1..8011e375 100644 --- a/reasoning_gym/graphs/family_relationships.py +++ b/reasoning_gym/graphs/family_relationships.py @@ -2,7 +2,7 @@ import random from dataclasses import dataclass, field from enum import StrEnum from itertools import count -from typing import List, Optional, Set, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -37,8 +37,8 @@ class Person: gender: Gender id: int spouse: Optional["Person"] = None - parents: List["Person"] = field(default_factory=list) - children: List["Person"] = field(default_factory=list) + parents: list["Person"] = field(default_factory=list) + children: list["Person"] = field(default_factory=list) def __hash__(self): return self.id @@ -65,7 +65,7 @@ class FamilyRelationshipsConfig: min_family_size: int = 4 max_family_size: int = 8 - male_names: List[str] = field( + male_names: list[str] = field( default_factory=lambda: [ "James", "John", @@ -112,7 +112,7 @@ class FamilyRelationshipsConfig: "Finn", ] ) - female_names: List[str] = field( + female_names: list[str] = field( default_factory=lambda: [ "Mary", "Patricia", @@ -207,7 +207,7 @@ class FamilyRelationshipsDataset(ProceduralDataset): }, } - def _generate_family(self, rng: random.Random) -> Set[Person]: + def _generate_family(self, rng: random.Random) -> set[Person]: """Generate a random family tree""" family_size = rng.randint(self.config.min_family_size, self.config.max_family_size) family = set() @@ -292,8 +292,8 @@ class FamilyRelationshipsDataset(ProceduralDataset): return family def _get_relationship_question( - self, rng: random.Random, family: Set[Person] - ) -> Tuple[Person, Person, Relationship]: + self, rng: random.Random, family: set[Person] + ) -> tuple[Person, Person, Relationship]: """Select two family members and determine their relationship""" person1, person2 = rng.sample(list(family), 2) @@ -326,7 +326,7 @@ class FamilyRelationshipsDataset(ProceduralDataset): return person1, person2, relationship - def _generate_story(self, family: Set[Person]) -> str: + def _generate_story(self, family: set[Person]) -> str: """Generate a story describing the family relationships""" story_parts = [] diff --git a/reasoning_gym/graphs/largest_island.py b/reasoning_gym/graphs/largest_island.py index 1b9269be..528a7713 100644 --- a/reasoning_gym/graphs/largest_island.py +++ b/reasoning_gym/graphs/largest_island.py @@ -7,7 +7,7 @@ https://leetcode.com/problems/max-area-of-island/description/ from collections import deque from dataclasses import dataclass from random import Random -from typing import List, Optional +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -58,7 +58,7 @@ class LargestIslandDataset(ProceduralDataset): def _is_valid_cell(self, r: int, c: int) -> bool: return 0 <= r < self.config.rows and 0 <= c < self.config.cols - def _create_grid(self, rng: Random) -> List[List[int]]: + def _create_grid(self, rng: Random) -> list[list[int]]: """Create a random grid of islands using a random walk algorithm""" grid = [[0] * self.config.cols for _ in range(self.config.rows)] directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Up, Down, Left, Right @@ -81,7 +81,7 @@ class LargestIslandDataset(ProceduralDataset): return grid - def _get_largest_island(self, grid: List[List[int]]) -> int: + def _get_largest_island(self, grid: list[list[int]]) -> int: """Find the largest island in the grid""" directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Up, Down, Left, Right visited = set() @@ -108,11 +108,11 @@ class LargestIslandDataset(ProceduralDataset): return max_area - def _grid_to_string(self, grid: List[List[int]]) -> str: + def _grid_to_string(self, grid: list[list[int]]) -> str: """Convert grid to a string representation""" return "\n".join(" ".join(str(cell) for cell in row) for row in grid) - def _string_to_board(self, grid_str: str) -> List[List[int]]: + def _string_to_board(self, grid_str: str) -> list[list[int]]: """Convert string representation to a grid""" return [[int(cell) for cell in row.split()] for row in grid_str.split("\n")] diff --git a/reasoning_gym/graphs/quantum_lock.py b/reasoning_gym/graphs/quantum_lock.py index 5863a5bf..4d810145 100644 --- a/reasoning_gym/graphs/quantum_lock.py +++ b/reasoning_gym/graphs/quantum_lock.py @@ -164,7 +164,7 @@ Buttons: # If no solution found, regenerate return self.generate_quantum_puzzle(rng, difficulty) - def score_answer(self, answer: Optional[str], entry: dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the task. The function awards 1.0 for a correct answer and less otherwise. diff --git a/reasoning_gym/logic/aiw.py b/reasoning_gym/logic/aiw.py index 00448280..7cabbb85 100644 --- a/reasoning_gym/logic/aiw.py +++ b/reasoning_gym/logic/aiw.py @@ -2,7 +2,7 @@ from dataclasses import dataclass, field from enum import StrEnum from random import Random from string import Template -from typing import List, Optional +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -20,15 +20,15 @@ class AliceInWonderlandConfig: """Configuration options for the Alice in Wonderland dataset. Attributes: - male_names (List[str]): List of male names to use in questions. - female_names (List[str]): List of female names to use in questions. Must include 'Alice'. - task_types (List[TaskType]): List of task types to include in dataset. + male_names (list[str]): List of male names to use in questions. + female_names (list[str]): List of female names to use in questions. Must include 'Alice'. + task_types (list[TaskType]): List of task types to include in dataset. seed (Optional[int]): Seed for random number generation. size (int): Number of samples in the dataset. max_entities (int): Max number of siblings/friends/colleagues in questions. """ - male_names: List[str] = field( + male_names: list[str] = field( default_factory=lambda: [ "James", "John", @@ -43,7 +43,7 @@ class AliceInWonderlandConfig: "Bob", ] ) - female_names: List[str] = field( + female_names: list[str] = field( default_factory=lambda: [ "Mary", "Patricia", @@ -58,7 +58,7 @@ class AliceInWonderlandConfig: "Alice", ] ) - task_types: List[TaskType] = field( + task_types: list[TaskType] = field( default_factory=lambda: [TaskType.SIBLINGS, TaskType.FRIENDS, TaskType.COLLEAGUES] # Added Colleagues ) seed: Optional[int] = None diff --git a/reasoning_gym/logic/circuit_logic.py b/reasoning_gym/logic/circuit_logic.py index d2219bf8..fd169076 100644 --- a/reasoning_gym/logic/circuit_logic.py +++ b/reasoning_gym/logic/circuit_logic.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -17,7 +17,7 @@ def _repeat(s: str, n: int) -> str: return s * n -def _matrix_put(matrix: List[List[str]], h: int, w: int, x: int, y: int, s: str, direction: str): +def _matrix_put(matrix: list[list[str]], h: int, w: int, x: int, y: int, s: str, direction: str): """Place a string `s` into the 2D `matrix` starting at (x,y), advancing in `direction` ('RIGHT' or 'DOWN').""" if x >= w or y >= h: @@ -119,14 +119,14 @@ class CircuitLogicDataset(ProceduralDataset): self._current_idx = 0 return self - def __next__(self) -> Dict[str, Any]: + def __next__(self) -> dict[str, Any]: if self._current_idx >= self.config.size: raise StopIteration item = self[self._current_idx] self._current_idx += 1 return item - def __getitem__(self, idx: int) -> Dict[str, Any]: + def __getitem__(self, idx: int) -> dict[str, Any]: """ Generate one random circuit logic item using ASCII drawing. """ @@ -142,14 +142,14 @@ class CircuitLogicDataset(ProceduralDataset): def _generate_circuit( self, rng: Random, num_terms: int, min_inputs: int, max_inputs: int, neg_prob: float, allow_reuse: bool - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Generate circuit logic (ASCII drawing + expression + evaluation) """ final_gate_name, final_gate_sym = rng.choice(self.final_gate_options) final_gate_width = 2 + len(final_gate_sym) - distinct_inputs: List[str] = [] + distinct_inputs: list[str] = [] def get_random_input() -> str: if allow_reuse and distinct_inputs and rng.random() < 0.5: @@ -159,8 +159,8 @@ class CircuitLogicDataset(ProceduralDataset): distinct_inputs.append(name) return name - term_ops: List[Tuple[str, str, str]] = [] - term_strings: List[str] = [] + term_ops: list[tuple[str, str, str]] = [] + term_strings: list[str] = [] for _ in range(num_terms): op = rng.choice(self.internal_ops) term_ops.append(op) @@ -400,7 +400,7 @@ class CircuitLogicDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, Any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: if answer is None or len(answer) == 0: return 0.0 diff --git a/reasoning_gym/logic/contrib/logic_puzzle/clues.py b/reasoning_gym/logic/contrib/logic_puzzle/clues.py index 1fddcc24..a753744e 100644 --- a/reasoning_gym/logic/contrib/logic_puzzle/clues.py +++ b/reasoning_gym/logic/contrib/logic_puzzle/clues.py @@ -14,7 +14,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field from functools import wraps from itertools import product -from typing import Iterable, List, Tuple +from typing import Iterable from reasoning_gym.logic.contrib.logic_puzzle.literals import Literal from reasoning_gym.logic.contrib.logic_puzzle.sat_utils import from_dnf, neg @@ -39,7 +39,7 @@ class Clue(ABC): """Base class for the types of clues that we allow.""" @abstractmethod - def as_cnf(self) -> Iterable[Tuple[str]]: ... + def as_cnf(self) -> Iterable[tuple[str]]: ... @abstractmethod def __repr__(self) -> str: ... @@ -67,7 +67,7 @@ class found_at(Clue): value: Literal house: int - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return [(comb(self.value, self.house),)] @_capitalize_first @@ -89,7 +89,7 @@ class not_at(Clue): value: Literal house: int - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return [(neg(comb(self.value, self.house)),)] @_capitalize_first @@ -110,9 +110,9 @@ class same_house(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf((comb(self.value1, i), comb(self.value2, i)) for i in self.houses) @_capitalize_first @@ -134,9 +134,9 @@ class consecutive(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf((comb(self.value1, i), comb(self.value2, j)) for i, j in zip(self.houses, self.houses[1:])) @_capitalize_first @@ -156,9 +156,9 @@ class beside(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf( [(comb(self.value1, i), comb(self.value2, j)) for i, j in zip(self.houses, self.houses[1:])] + [(comb(self.value2, i), comb(self.value1, j)) for i, j in zip(self.houses, self.houses[1:])] @@ -182,9 +182,9 @@ class left_of(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf( (comb(self.value1, i), comb(self.value2, j)) for i, j in product(self.houses, self.houses) if i < j ) @@ -207,9 +207,9 @@ class right_of(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return sat_utils.from_dnf( (comb(self.value1, i), comb(self.value2, j)) for i, j in product(self.houses, self.houses) if i > j ) @@ -233,9 +233,9 @@ class one_between(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf( [(comb(self.value1, i), comb(self.value2, j)) for i, j in zip(self.houses, self.houses[2:])] + [(comb(self.value2, i), comb(self.value1, j)) for i, j in zip(self.houses, self.houses[2:])] @@ -257,9 +257,9 @@ class two_between(Clue): value1: Literal value2: Literal - houses: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) + houses: tuple[int, ...] = field(default_factory=lambda: (1, 2, 3, 4, 5)) - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: return from_dnf( [(comb(self.value1, i), comb(self.value2, j)) for i, j in zip(self.houses, self.houses[3:])] + [(comb(self.value2, i), comb(self.value1, j)) for i, j in zip(self.houses, self.houses[3:])] diff --git a/reasoning_gym/logic/contrib/logic_puzzle/generate.py b/reasoning_gym/logic/contrib/logic_puzzle/generate.py index 4012655b..9bc4bb02 100644 --- a/reasoning_gym/logic/contrib/logic_puzzle/generate.py +++ b/reasoning_gym/logic/contrib/logic_puzzle/generate.py @@ -7,7 +7,7 @@ This is a driver script that can be used to generate new zebra puzzles. from collections import OrderedDict from itertools import product from random import Random -from typing import Dict, Iterable, List, Set, Tuple, Type +from typing import Iterable, Type from tabulate import tabulate @@ -18,18 +18,18 @@ from reasoning_gym.logic.contrib.logic_puzzle.sat_utils import itersolve from .clues import Clue, beside, consecutive, found_at, left_of, not_at, one_between, right_of, same_house, two_between -def generate_found_at(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> Set[Clue]: +def generate_found_at(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> set[Clue]: """Generate the `found_at` / `not_at` Clue instances""" - clues: Set[Clue] = set() + clues: set[Clue] = set() for element, loc in solution.items(): clues.add(found_at(element, loc)) return clues -def generate_not_found_at(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[Clue]: +def generate_not_found_at(puzzle: Puzzle, solution: dict[Literal, int]) -> set[Clue]: """Generate the `found_at` / `not_at` Clue instances""" - clues: Set[Clue] = set() + clues: set[Clue] = set() for element, loc in solution.items(): for house in puzzle.houses: if house != loc: @@ -38,13 +38,13 @@ def generate_not_found_at(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[C return clues -def generate_same_house(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> Set[Clue]: +def generate_same_house(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> set[Clue]: """Generate the `same_house` Clue instances""" - clues: Set[Clue] = set() + clues: set[Clue] = set() for house in puzzle.houses: items_at_house = {item: loc for item, loc in solution.items() if loc == house} - pairs: Set[Tuple[Literal, Literal]] = { + pairs: set[tuple[Literal, Literal]] = { (item1, item2) for item1, item2 in product(items_at_house, repeat=2) if item1 != item2 } for pair in pairs: @@ -53,18 +53,18 @@ def generate_same_house(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> return clues -def generate_consecutive_beside(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> Set[Clue]: +def generate_consecutive_beside(puzzle: Puzzle, solution: OrderedDict[Literal, int]) -> set[Clue]: """Generate the `consecutive` / `beside` Clue instances (Note that consecutive is just a more informative version of beside. Since they have the same structure, for every possible combination we'll just keep one. """ - clues: Set[Clue] = set() + clues: set[Clue] = set() for left, right in zip(puzzle.houses, puzzle.houses[1:]): items_left = {item: loc for item, loc in solution.items() if loc == left} items_right = {item: loc for item, loc in solution.items() if loc == right} - pairs: Set[Tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} + pairs: set[tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} # sorted, no hash randomization for pair in sorted(pairs): # consecutive is just a more informative version of beside, but they have same structure @@ -77,20 +77,20 @@ def generate_consecutive_beside(puzzle: Puzzle, solution: OrderedDict[Literal, i return clues -def generate_left_right_of(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[Clue]: +def generate_left_right_of(puzzle: Puzzle, solution: dict[Literal, int]) -> set[Clue]: """Generate the `left_of` / `right_of` Clue instances Note that since (x left-of y) is guaranteed to be redundant with (b right-of a), we only add one of these clues to the final set. """ - clues: Set[Clue] = set() + clues: set[Clue] = set() for left, right in product(puzzle.houses, puzzle.houses): if left >= right: continue items_left = {item: loc for item, loc in solution.items() if loc == left} items_right = {item: loc for item, loc in solution.items() if loc == right} - pairs: Set[Tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} + pairs: set[tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} # sorted, no hash randomization for pair in sorted(pairs): if puzzle.rng.randint(0, 1) == 0: @@ -101,28 +101,28 @@ def generate_left_right_of(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[ return clues -def generate_one_between(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[Clue]: +def generate_one_between(puzzle: Puzzle, solution: dict[Literal, int]) -> set[Clue]: """Generate the `one_between` Clue instances""" - clues: Set[Clue] = set() + clues: set[Clue] = set() for left, right in zip(puzzle.houses, puzzle.houses[2:]): items_left = {item: loc for item, loc in solution.items() if loc == left} items_right = {item: loc for item, loc in solution.items() if loc == right} - pairs: Set[Tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} + pairs: set[tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} for pair in pairs: clues.add(one_between(pair[0], pair[1], puzzle.houses)) return clues -def generate_two_between(puzzle: Puzzle, solution: Dict[Literal, int]) -> Set[Clue]: +def generate_two_between(puzzle: Puzzle, solution: dict[Literal, int]) -> set[Clue]: """Generate the `two_between` Clue instances""" - clues: Set[Clue] = set() + clues: set[Clue] = set() for left, right in zip(puzzle.houses, puzzle.houses[3:]): items_left = {item: loc for item, loc in solution.items() if loc == left} items_right = {item: loc for item, loc in solution.items() if loc == right} - pairs: Set[Tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} + pairs: set[tuple[Literal, Literal]] = {(item1, item2) for item1, item2 in product(items_left, items_right)} for pair in pairs: clues.add(two_between(pair[0], pair[1], puzzle.houses)) @@ -144,7 +144,7 @@ def has_unique_solution(puzzle: Puzzle, clues: Iterable[Clue]) -> bool: return False -def try_to_remove(puzzle: Puzzle, clues: Set[Clue], n: int, must_have=set()) -> Set[Clue]: +def try_to_remove(puzzle: Puzzle, clues: set[Clue], n: int, must_have=set()) -> set[Clue]: """ Attempt to remove n clues from a set of candidate clues; if we are able to, return the new, smaller set of clues. If not, return the original set. @@ -152,7 +152,7 @@ def try_to_remove(puzzle: Puzzle, clues: Set[Clue], n: int, must_have=set()) -> def weight(clue: Clue) -> float: # relative probabilities of each type of clue being selected for removal - weights: Dict[Type[Clue], float] = { + weights: dict[Type[Clue], float] = { not_at: 0.75, found_at: 0.75, same_house: 0.75, @@ -167,7 +167,7 @@ def try_to_remove(puzzle: Puzzle, clues: Set[Clue], n: int, must_have=set()) -> # sorted, no hash randomization weights = [weight(clue) for clue in sorted(clues)] - candidates: Set[Clue] = set(puzzle.rng.choices(sorted(clues), weights, k=n)) + candidates: set[Clue] = set(puzzle.rng.choices(sorted(clues), weights, k=n)) candidates = candidates - must_have clues = clues.difference(candidates) if has_unique_solution(puzzle, clues): @@ -180,8 +180,8 @@ def try_to_remove(puzzle: Puzzle, clues: Set[Clue], n: int, must_have=set()) -> def reduce_individually( - puzzle: Puzzle, clues: Set[Clue], removed: Set[Clue], must_have=set() -) -> Tuple[Set[Clue], Set[Clue]]: + puzzle: Puzzle, clues: set[Clue], removed: set[Clue], must_have=set() +) -> tuple[set[Clue], set[Clue]]: """ Attempt to remove each candidate clue one by one. @@ -202,7 +202,7 @@ def reduce_individually( return clues, removed -def reduce_clues(puzzle: Puzzle, clues: Set[Clue], must_have=set()) -> Tuple[Set[Clue], Set[Clue]]: +def reduce_clues(puzzle: Puzzle, clues: set[Clue], must_have=set()) -> tuple[set[Clue], set[Clue]]: """ Reduce a set of clues to a minimally solvable set. @@ -265,7 +265,7 @@ def reduce_clues(puzzle: Puzzle, clues: Set[Clue], must_have=set()) -> Tuple[Set # secondary reduction time! While we can still remove clues, do so; then we're done. # print(f"Starting the secondary reduction.") - removed_clues: Set[Clue] = set() + removed_clues: set[Clue] = set() while True: minimal_clues_size = len(minimal_clues) minimal_clues, removed_clues = reduce_individually(puzzle, minimal_clues, removed_clues, must_have) @@ -304,12 +304,12 @@ def question_generation(rng: Random, col_name, table_data): return questions_data -def generate_solution_dict(rng: Random, selected_elements: List[Literal], n: int) -> OrderedDict[Literal, int]: +def generate_solution_dict(rng: Random, selected_elements: list[Literal], n: int) -> OrderedDict[Literal, int]: solution = OrderedDict() house_ids = list(range(1, n + 1)) for element in selected_elements: rng.shuffle(house_ids) - attributes: List[Literal] = sorted(element.__members__.values()) + attributes: list[Literal] = sorted(element.__members__.values()) for i in range(n): solution[attributes[i]] = house_ids[i] return solution @@ -376,7 +376,7 @@ def generate_puzzle(rng: Random, K=2, M=3) -> tuple[OrderedDict, Puzzle]: context = str(puzzle) # generate all the clues - clues: Set[Clue] = set() + clues: set[Clue] = set() for generate_function in clue_types: clues = clues.union(generate_function(puzzle, solution)) diff --git a/reasoning_gym/logic/contrib/logic_puzzle/puzzle.py b/reasoning_gym/logic/contrib/logic_puzzle/puzzle.py index 6aba4545..640b3a0f 100644 --- a/reasoning_gym/logic/contrib/logic_puzzle/puzzle.py +++ b/reasoning_gym/logic/contrib/logic_puzzle/puzzle.py @@ -7,7 +7,7 @@ from __future__ import annotations from contextlib import contextmanager from random import Random -from typing import Generator, Iterable, List, Set, Tuple, Type +from typing import Generator, Iterable, Type from reasoning_gym.logic.contrib.logic_puzzle.clues import ( Clue, @@ -82,12 +82,12 @@ class Puzzle: self.literals = list(elements) self.houses = tuple(range(1, n_houses + 1)) - self.clues: Set[Clue] = set() - self.constraints: List[Tuple[str]] = [] - self.extra_clues: Set[Clue] = set() + self.clues: set[Clue] = set() + self.constraints: list[tuple[str]] = [] + self.extra_clues: set[Clue] = set() self.solution = None - def _add_constraint(self, constraints: List[Tuple[str]]) -> Puzzle: + def _add_constraint(self, constraints: list[tuple[str]]) -> Puzzle: self.constraints.extend(constraints) return self @@ -128,7 +128,7 @@ class Puzzle: return self - def as_cnf(self) -> List[Tuple[str]]: + def as_cnf(self) -> list[tuple[str]]: """Express puzzle as solvable CNF""" # this would be a comprehension if we could use iterable unpacking @@ -195,8 +195,8 @@ they smoke, and what pet they own. """ if __name__ == "__main__": - enum_classes: List[Type[Literal]] = [Color, Nationality, Animal, Drink, Cigar] - literals: List[Literal] = [el for group in enum_classes for el in group] + enum_classes: list[Type[Literal]] = [Color, Nationality, Animal, Drink, Cigar] + literals: list[Literal] = [el for group in enum_classes for el in group] # set up the puzzle with constraints and clues puzzle = Puzzle(rng=Random(), element_types=[Color, Nationality, Drink, Cigar, Animal]) @@ -245,7 +245,7 @@ in between them that neither is sitting in). """ if __name__ == "__main__": - enum_classes: List[Type[Literal]] = [Mother, Children, Flower, Food] + enum_classes: list[Type[Literal]] = [Mother, Children, Flower, Food] literals = [el for group in enum_classes for el in group] # set up the puzzle with constraints and clues diff --git a/reasoning_gym/logic/contrib/logic_puzzle/sat_utils.py b/reasoning_gym/logic/contrib/logic_puzzle/sat_utils.py index df5e26e9..5454aef1 100644 --- a/reasoning_gym/logic/contrib/logic_puzzle/sat_utils.py +++ b/reasoning_gym/logic/contrib/logic_puzzle/sat_utils.py @@ -4,15 +4,15 @@ __author__ = "Raymond Hettinger" from functools import lru_cache from itertools import combinations -from typing import Dict, FrozenSet, Iterable, List, Set, Tuple +from typing import FrozenSet, Iterable import pycosat Element = str # literal; any string, but here it's e.g., "tushar 5" or "chai 2" -CNF = List[Tuple[Element, ...]] +CNF = list[tuple[Element, ...]] -def make_translate(cnf: CNF) -> Tuple[Dict[Element, int], Dict[int, Element]]: +def make_translate(cnf: CNF) -> tuple[dict[Element, int], dict[int, Element]]: """Make a translator from symbolic CNF to pycosat's numbered clauses. Return literal to number dictionary and reverse lookup dict. @@ -22,7 +22,7 @@ def make_translate(cnf: CNF) -> Tuple[Dict[Element, int], Dict[int, Element]]: {1: 'a', 2: 'b', 3: 'c', -1: '~a', -3: '~c', -2: '~b'}) """ - lit2num: Dict[Element, int] = {} + lit2num: dict[Element, int] = {} for clause in cnf: for literal in clause: if literal not in lit2num: @@ -36,7 +36,7 @@ def make_translate(cnf: CNF) -> Tuple[Dict[Element, int], Dict[int, Element]]: return lit2num, num2var -def translate(cnf: CNF, uniquify=False) -> Tuple[List[Tuple[int, ...]], Dict[int, Element]]: +def translate(cnf: CNF, uniquify=False) -> tuple[list[tuple[int, ...]], dict[int, Element]]: """Translate a symbolic CNF to a numbered CNF and return reverse mapping. >>> translate([['~P', 'Q'],['~P', 'R']]) @@ -78,14 +78,14 @@ def neg(element: str) -> str: return element[1:] if element.startswith("~") else "~" + element -def from_dnf(groups: Iterable[Tuple[str, ...]]) -> CNF: +def from_dnf(groups: Iterable[tuple[str, ...]]) -> CNF: """Convert from or-of-ands to and-of-ors >>> from_dnf([['~P'], ['Q', 'R']]) [('~P', 'Q'), ('~P', 'R')] """ - cnf: Set[FrozenSet[str]] = {frozenset()} + cnf: set[FrozenSet[str]] = {frozenset()} for group in groups: nl = {frozenset([literal]): neg(literal) for literal in group} # The "clause | literal" prevents dup lits: {x, x, y} -> {x, y} @@ -134,7 +134,7 @@ class Q: return f"{self.__class__.__name__}(elements={self.elements!r})" -def all_of(elements: List[Element]) -> CNF: +def all_of(elements: list[Element]) -> CNF: """Forces inclusion of matching rows on a truth table""" return Q(elements) == len(elements) diff --git a/reasoning_gym/logic/propositional_logic.py b/reasoning_gym/logic/propositional_logic.py index 395c919f..bd8072d3 100644 --- a/reasoning_gym/logic/propositional_logic.py +++ b/reasoning_gym/logic/propositional_logic.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from enum import StrEnum from random import Random -from typing import Any, List, Optional, Set +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -123,7 +123,7 @@ class PropositionalLogicDataset(ProceduralDataset): }, } - def _generate_premises(self, rng: Random, variables: List[str], num_statements: int) -> List[Expression]: + def _generate_premises(self, rng: Random, variables: list[str], num_statements: int) -> list[Expression]: """Generate a list of premise statements""" premises = [] for _ in range(num_statements): @@ -131,7 +131,7 @@ class PropositionalLogicDataset(ProceduralDataset): premises.append(self._generate_expression(rng, variables, depth)) return premises - def _generate_expression(self, rng: Random, variables: List[str], depth: int) -> Expression: + def _generate_expression(self, rng: Random, variables: list[str], depth: int) -> Expression: """Generate a random logical expression""" if depth <= 1: return Expression(None, rng.choice(variables)) @@ -144,7 +144,7 @@ class PropositionalLogicDataset(ProceduralDataset): right = self._generate_expression(rng, variables, depth - 1) return Expression(operator, left, right) - def _find_valid_conclusion(self, rng: Random, premises: List[Expression], variables: List[str]) -> Expression: + def _find_valid_conclusion(self, rng: Random, premises: list[Expression], variables: list[str]) -> Expression: """Find a valid conclusion that follows from the premises""" # Try random conclusions until we find a valid one for _ in range(100): @@ -155,7 +155,7 @@ class PropositionalLogicDataset(ProceduralDataset): # Fallback to a simple conclusion return Expression(None, variables[0]) - def _is_valid_conclusion(self, premises: List[Expression], conclusion: Expression) -> bool: + def _is_valid_conclusion(self, premises: list[Expression], conclusion: Expression) -> bool: """Check if conclusion follows from premises using truth tables""" variables = self._collect_variables(premises + [conclusion]) @@ -166,7 +166,7 @@ class PropositionalLogicDataset(ProceduralDataset): return False return True - def _collect_variables(self, expressions: List[Expression]) -> Set[str]: + def _collect_variables(self, expressions: list[Expression]) -> set[str]: """Collect all variables used in expressions""" variables = set() for expr in expressions: @@ -179,7 +179,7 @@ class PropositionalLogicDataset(ProceduralDataset): variables.update(self._collect_variables([expr.right])) return variables - def _generate_assignments(self, variables: Set[str]) -> List[dict[str, bool]]: + def _generate_assignments(self, variables: set[str]) -> list[dict[str, bool]]: """Generate all possible truth value assignments""" assignments = [] for i in range(2 ** len(variables)): diff --git a/reasoning_gym/logic/self_reference.py b/reasoning_gym/logic/self_reference.py index d8155b4c..f42ce415 100644 --- a/reasoning_gym/logic/self_reference.py +++ b/reasoning_gym/logic/self_reference.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset @@ -349,14 +349,14 @@ class SelfReferenceDataset(ProceduralDataset): "metadata": {}, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the SelfReference task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/logic/syllogisms.py b/reasoning_gym/logic/syllogisms.py index 00e4a37b..9546ad1d 100644 --- a/reasoning_gym/logic/syllogisms.py +++ b/reasoning_gym/logic/syllogisms.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from enum import StrEnum from random import Random -from typing import List, Optional, Tuple +from typing import Optional from ..factory import ProceduralDataset, register_dataset @@ -105,7 +105,7 @@ class SyllogismDataset(ProceduralDataset): super().__init__(config=config, seed=config.seed, size=config.size) self.terms = self.DEFAULT_TERMS - def _get_allowed_quantifiers(self) -> List[Quantifier]: + def _get_allowed_quantifiers(self) -> list[Quantifier]: """Get list of allowed quantifiers based on config""" quantifiers = [] if self.config.allow_all: @@ -120,9 +120,9 @@ class SyllogismDataset(ProceduralDataset): @staticmethod def _is_valid_syllogism( - premise1: Tuple[Quantifier, "Term", "Term"], - premise2: Tuple[Quantifier, "Term", "Term"], - conclusion: Tuple[Quantifier, "Term", "Term"], + premise1: tuple[Quantifier, "Term", "Term"], + premise2: tuple[Quantifier, "Term", "Term"], + conclusion: tuple[Quantifier, "Term", "Term"], ) -> bool: """ Checks whether a given syllogism is valid under classical (Aristotelian) rules, @@ -247,7 +247,7 @@ class SyllogismDataset(ProceduralDataset): return f"{quantifier.value} {subject.plural} are {predicate.plural}" def _check_logical_equivalence( - self, premise: Tuple[Quantifier, Term, Term], conclusion: Tuple[Quantifier, Term, Term] + self, premise: tuple[Quantifier, Term, Term], conclusion: tuple[Quantifier, Term, Term] ) -> bool: """Check if a conclusion is logically equivalent to a premise""" p_quant, p_subj, p_pred = premise diff --git a/reasoning_gym/logic/zebra_puzzles.py b/reasoning_gym/logic/zebra_puzzles.py index 38cbe051..c518c65d 100644 --- a/reasoning_gym/logic/zebra_puzzles.py +++ b/reasoning_gym/logic/zebra_puzzles.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from random import Random -from typing import Dict, Optional +from typing import Any, Optional from ..factory import ProceduralDataset, register_dataset from .contrib.logic_puzzle.generate import generate_puzzle @@ -55,14 +55,14 @@ class ZebraDataset(ProceduralDataset): }, } - def score_answer(self, answer: Optional[str], entry: Dict[str, any]) -> float: + def score_answer(self, answer: Optional[str], entry: dict[str, Any]) -> float: """Determine if the solution provided solves the Zebra task. The function awards 1.0 for a correct answer. Args: answer (Optional[str]): The user's answer. - entry (Dict[str, any]): The original dataset entry containing the correct answer. + entry (dict[str, Any]): The original dataset entry containing the correct answer. Returns: float: The computed score between 0.0 and 1.0. diff --git a/reasoning_gym/version_manager.py b/reasoning_gym/version_manager.py index dbe19a09..9b01f075 100644 --- a/reasoning_gym/version_manager.py +++ b/reasoning_gym/version_manager.py @@ -1,6 +1,6 @@ """Version manager for tracking dataset versions.""" -from typing import Dict, Optional, Tuple +from typing import Any, Optional from .dataset import ProceduralDataset @@ -12,7 +12,7 @@ class DatasetVersionManager: """Initialize the version manager.""" self.current_version = 0 # version_id -> (dataset_name, dataset_instance) - self.datasets: Dict[int, Tuple[str, ProceduralDataset]] = {} + self.datasets: dict[int, tuple[str, ProceduralDataset]] = {} def register_dataset(self, name: str, dataset: ProceduralDataset) -> int: """ @@ -29,7 +29,7 @@ class DatasetVersionManager: self.datasets[self.current_version] = (name, dataset) return self.current_version - def get_dataset(self, version_id: int) -> Optional[Tuple[str, ProceduralDataset]]: + def get_dataset(self, version_id: int) -> Optional[tuple[str, ProceduralDataset]]: """ Retrieve a dataset by its version ID. @@ -41,7 +41,7 @@ class DatasetVersionManager: """ return self.datasets.get(version_id) - def get_entry(self, version_id: int, index: int) -> Dict[str, any]: + def get_entry(self, version_id: int, index: int) -> dict[str, Any]: """ Get a specific entry from a versioned dataset. diff --git a/tests/test_coaching.py b/tests/test_coaching.py index 3b1b97d7..56e58548 100644 --- a/tests/test_coaching.py +++ b/tests/test_coaching.py @@ -1,7 +1,6 @@ import json import math from collections import OrderedDict -from pathlib import Path import pytest diff --git a/tools/cli/rgc/client.py b/tools/cli/rgc/client.py index 4808a0fe..48791377 100644 --- a/tools/cli/rgc/client.py +++ b/tools/cli/rgc/client.py @@ -105,7 +105,7 @@ class RGClient: response.raise_for_status() return BatchResponse.model_validate(response.json()) - def score_outputs(self, experiment: str, entry_answers: List[AnswerItem]) -> ScoringResponse: + def score_outputs(self, experiment: str, entry_answers: list[AnswerItem]) -> ScoringResponse: """Score a batch of answers. Args: diff --git a/tools/server/models.py b/tools/server/models.py index 6c873b08..1b6b505c 100644 --- a/tools/server/models.py +++ b/tools/server/models.py @@ -1,6 +1,6 @@ """Pydantic models for API request/response data.""" -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from pydantic import BaseModel, Field @@ -11,7 +11,7 @@ class ExperimentCreate(BaseModel): name: str = Field(..., description="Unique name for the experiment") size: int = Field(500, description="Size of the dataset") seed: Optional[int] = Field(None, description="Random seed for reproducibility") - datasets: Dict[str, Dict[str, Any]] = Field(..., description="Dictionary of datasets configurations") + datasets: dict[str, dict[str, Any]] = Field(..., description="Dictionary of datasets configurations") class ExperimentResponse(BaseModel): @@ -20,19 +20,19 @@ class ExperimentResponse(BaseModel): name: str = Field(..., description="Name of the experiment") size: int = Field(..., description="Size of the dataset") seed: Optional[int] = Field(None, description="Random seed used") - datasets: Dict[str, Dict[str, Any]] = Field(..., description="Current dataset configurations") + datasets: dict[str, dict[str, Any]] = Field(..., description="Current dataset configurations") class ExperimentList(BaseModel): """Response model for listing experiments.""" - experiments: List[str] = Field(default_factory=list, description="List of registered experiment names") + experiments: list[str] = Field(default_factory=list, description="List of registered experiment names") class DatasetConfigUpdate(BaseModel): """Request model for updating dataset configuration.""" - config: Dict[str, Any] = Field(..., description="Configuration parameters to update") + config: dict[str, Any] = Field(..., description="Configuration parameters to update") class ErrorResponse(BaseModel): @@ -46,13 +46,13 @@ class BatchEntry(BaseModel): question: str = Field(..., description="The question text") entry_id: str = Field(..., description="Unique identifier in format '{version}.{index}'") - metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata about the entry") + metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata about the entry") class BatchResponse(BaseModel): """Response containing a batch of entries""" - entries: List[BatchEntry] = Field(..., description="List of batch entries") + entries: list[BatchEntry] = Field(..., description="List of batch entries") class AnswerItem(BaseModel): @@ -65,11 +65,11 @@ class AnswerItem(BaseModel): class ScoringRequest(BaseModel): """Request for scoring model outputs""" - answers: List[AnswerItem] = Field(..., description="List of entries to score") + answers: list[AnswerItem] = Field(..., description="List of entries to score") class ScoringResponse(BaseModel): """Response containing scores for answers""" - scores: List[float] = Field(..., description="List of scores in same order as request") - entry_ids: List[str] = Field(..., description="List of entry_ids in same order as request") + scores: list[float] = Field(..., description="List of scores in same order as request") + entry_ids: list[str] = Field(..., description="List of entry_ids in same order as request")