feat: natural sort cases
All checks were successful
build / build (push) Successful in 2m39s
build / trigger-build-image (push) Successful in 19s

This commit is contained in:
张泊明518370910136 2025-11-21 20:12:27 -08:00
parent 4b2e818538
commit 4d7c7aa344
GPG Key ID: D47306D7062CDA9D
4 changed files with 74 additions and 63 deletions

View File

@ -2,7 +2,9 @@ import re
import shlex import shlex
from functools import partial from functools import partial
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
from typing import Any, Callable, Dict, List, Optional, Tuple, Union from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
from natsort import natsorted
from joj3_config_generator.models import result, task from joj3_config_generator.models import result, task
from joj3_config_generator.models.common import StrictBaseModel from joj3_config_generator.models.common import StrictBaseModel
@ -216,10 +218,12 @@ def fix_diff(
task_root, task_path, case_base_dir, task_stage.cases task_root, task_path, case_base_dir, task_stage.cases
) )
# cases specified in toml config but not skipped # cases specified in toml config but not skipped
specified_cases = [(case, task_stage.cases[case]) for case in task_stage.cases] specified_cases = task_stage.cases
stage_cases = [] stage_cases = []
parser_cases = [] parser_cases = []
for case_name, case in specified_cases: collected_cases = []
for case_name in specified_cases:
case = task_stage.cases[case_name]
stdin, stdout = get_stdin_stdout( stdin, stdout = get_stdin_stdout(
task_root, task_path, case_base_dir, case_name, case task_root, task_path, case_base_dir, case_name, case
) )
@ -248,7 +252,6 @@ def fix_diff(
cmd.memory_limit = None cmd.memory_limit = None
if cmd.proc_limit == executor.with_.default.proc_limit: if cmd.proc_limit == executor.with_.default.proc_limit:
cmd.proc_limit = None cmd.proc_limit = None
stage_cases.append(cmd)
def get_diff_attribute(attribute_name: str) -> Any: def get_diff_attribute(attribute_name: str) -> Any:
if case.diff and attribute_name in case.diff.model_fields_set: if case.diff and attribute_name in case.diff.model_fields_set:
@ -270,12 +273,11 @@ def fix_diff(
) )
] ]
) )
parser_cases.append(parser_case) collected_cases.append((case_name, cmd, parser_case))
for case_name in unspecified_cases: for case_name in unspecified_cases:
cmd = result.OptionalCmd( cmd = result.OptionalCmd(
stdin=result.LocalFile(src=str(base_dir / f"{case_name}.in")), stdin=result.LocalFile(src=str(base_dir / f"{case_name}.in")),
) )
stage_cases.append(cmd)
parser_case = result.DiffCasesConfig( parser_case = result.DiffCasesConfig(
outputs=[ outputs=[
result.DiffOutputConfig( result.DiffOutputConfig(
@ -291,14 +293,17 @@ def fix_diff(
) )
] ]
) )
parser_cases.append(parser_case) collected_cases.append((case_name, cmd, parser_case))
sorted_collected_cases = natsorted(collected_cases, key=lambda x: x[0])
stage_cases = [x[1] for x in sorted_collected_cases]
parser_cases = [x[2] for x in sorted_collected_cases]
executor.with_.cases = stage_cases executor.with_.cases = stage_cases
diff_parser.with_ = result.DiffConfig(name="diff", cases=parser_cases) diff_parser.with_ = result.DiffConfig(name="diff", cases=parser_cases)
def get_unspecified_cases( def get_unspecified_cases(
task_root: Path, task_path: Path, case_base_dir: Path, cases: Dict[str, task.Case] task_root: Path, task_path: Path, case_base_dir: Path, cases: Dict[str, task.Case]
) -> List[str]: ) -> Set[str]:
testcases = set() testcases = set()
for testcases_path in ((task_root / task_path).parent / case_base_dir).glob( for testcases_path in ((task_root / task_path).parent / case_base_dir).glob(
"**/*.in" "**/*.in"
@ -317,14 +322,8 @@ def get_unspecified_cases(
) )
).removesuffix(".in") ).removesuffix(".in")
) )
return sorted( return testcases.difference(
testcases.difference( casei for casei in testcases if any(casei.endswith(casej) for casej in cases)
[
casei
for casei in testcases
if any(casei.endswith(casej) for casej in cases)
]
)
) )

View File

@ -5,7 +5,7 @@
groups = ["default", "dev", "lint", "test"] groups = ["default", "dev", "lint", "test"]
strategy = ["inherit_metadata"] strategy = ["inherit_metadata"]
lock_version = "4.5.0" lock_version = "4.5.0"
content_hash = "sha256:0d342f3006bcf50ba9bf77ee49f2b03705b001e9e558d401ef66d24f74610b92" content_hash = "sha256:4e3b17128a8476ddabd32870991976c85a00b63c7a3d5e9d3f58d892375370d5"
[[metadata.targets]] [[metadata.targets]]
requires_python = ">=3.9" requires_python = ">=3.9"
@ -494,6 +494,17 @@ files = [
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
] ]
[[package]]
name = "natsort"
version = "8.4.0"
requires_python = ">=3.7"
summary = "Simple yet flexible natural sorting in Python."
groups = ["default"]
files = [
{file = "natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c"},
{file = "natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581"},
]
[[package]] [[package]]
name = "nodeenv" name = "nodeenv"
version = "1.9.1" version = "1.9.1"

View File

@ -15,6 +15,7 @@ dependencies = [
"tomlkit>=0.13.2", "tomlkit>=0.13.2",
"tomli>=2.2.1", "tomli>=2.2.1",
"setuptools-scm>=9.2.0", "setuptools-scm>=9.2.0",
"natsort>=8.4.0",
] ]
requires-python = ">=3.9" requires-python = ">=3.9"
authors = [{ name = "JOJ3-dev", email = "joj3@focs.ji.sjtu.edu.cn" }] authors = [{ name = "JOJ3-dev", email = "joj3@focs.ji.sjtu.edu.cn" }]

View File

@ -87,17 +87,7 @@
}, },
{ {
"stdin": { "stdin": {
"src": "/home/tt/.config/joj/diff/case9.in" "src": "/home/tt/.config/joj/diff/case2.in"
}
},
{
"stdin": {
"src": "/home/tt/.config/joj/diff/task1/subtask1/case11.in"
}
},
{
"stdin": {
"src": "/home/tt/.config/joj/diff/task1/subtask1/case10.in"
} }
}, },
{ {
@ -107,7 +97,17 @@
}, },
{ {
"stdin": { "stdin": {
"src": "/home/tt/.config/joj/diff/case2.in" "src": "/home/tt/.config/joj/diff/case9.in"
}
},
{
"stdin": {
"src": "/home/tt/.config/joj/diff/task1/subtask1/case10.in"
}
},
{
"stdin": {
"src": "/home/tt/.config/joj/diff/task1/subtask1/case11.in"
} }
}, },
{ {
@ -172,39 +172,9 @@
{ {
"outputs": [ "outputs": [
{ {
"score": 1232131, "score": 100,
"filename": "stdout", "filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/case9.out", "answerPath": "/home/tt/.config/joj/diff/case2.out",
"compareSpace": false,
"alwaysHide": false,
"forceQuitOnDiff": false,
"maxDiffLength": 2048,
"maxDiffLines": 50,
"hideCommonPrefix": false
}
]
},
{
"outputs": [
{
"score": 92321,
"filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/task1/subtask1/case11.out",
"compareSpace": false,
"alwaysHide": false,
"forceQuitOnDiff": false,
"maxDiffLength": 2048,
"maxDiffLines": 50,
"hideCommonPrefix": false
}
]
},
{
"outputs": [
{
"score": 823131,
"filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/task1/subtask1/case10.out",
"compareSpace": false, "compareSpace": false,
"alwaysHide": false, "alwaysHide": false,
"forceQuitOnDiff": false, "forceQuitOnDiff": false,
@ -232,9 +202,39 @@
{ {
"outputs": [ "outputs": [
{ {
"score": 100, "score": 1232131,
"filename": "stdout", "filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/case2.out", "answerPath": "/home/tt/.config/joj/diff/case9.out",
"compareSpace": false,
"alwaysHide": false,
"forceQuitOnDiff": false,
"maxDiffLength": 2048,
"maxDiffLines": 50,
"hideCommonPrefix": false
}
]
},
{
"outputs": [
{
"score": 823131,
"filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/task1/subtask1/case10.out",
"compareSpace": false,
"alwaysHide": false,
"forceQuitOnDiff": false,
"maxDiffLength": 2048,
"maxDiffLines": 50,
"hideCommonPrefix": false
}
]
},
{
"outputs": [
{
"score": 92321,
"filename": "stdout",
"answerPath": "/home/tt/.config/joj/diff/task1/subtask1/case11.out",
"compareSpace": false, "compareSpace": false,
"alwaysHide": false, "alwaysHide": false,
"forceQuitOnDiff": false, "forceQuitOnDiff": false,