mirror of
https://github.com/calesthio/OpenMontage.git
synced 2026-08-05 15:20:40 +08:00
fix(variation_checker): measure longest run for consecutive same-size shots
Check 2 flagged 'N consecutive same-size shots' from a count of every equal adjacent pair across the whole plan, not the length of any real run. So three separate 2-shot groups (wide,wide,cu,cu,med,med) tripped a false '3 consecutive' violation, while a genuine run of 3 (only 2 pairs) was never flagged. Track the current run length, reset on change, and compare the longest run >= 3. Adds regression tests: non-consecutive pairs pass, a true run of 3 is flagged, unspecified shots don't form a run. Closes #268
This commit is contained in:
@@ -56,13 +56,20 @@ def check_scene_variation(scenes: list[dict[str, Any]]) -> dict[str, Any]:
|
||||
suggestions.append("Mix wide establishing shots with close-ups for visual rhythm.")
|
||||
|
||||
# --- Check 2: Consecutive same-size shots ---
|
||||
consecutive_same = 0
|
||||
# Track the longest actual run of identical shot sizes. Summing every equal
|
||||
# adjacent pair across the whole plan would count non-consecutive groups
|
||||
# (e.g. wide,wide,cu,cu,med,med -> 3 pairs) as a single "3 consecutive" run.
|
||||
longest_run = 1 if shot_sizes else 0
|
||||
current_run = 1
|
||||
for i in range(1, len(shot_sizes)):
|
||||
if shot_sizes[i] == shot_sizes[i-1] and shot_sizes[i] != "unspecified":
|
||||
consecutive_same += 1
|
||||
if consecutive_same >= 3:
|
||||
current_run += 1
|
||||
longest_run = max(longest_run, current_run)
|
||||
else:
|
||||
current_run = 1
|
||||
if longest_run >= 3:
|
||||
violations.append(
|
||||
f"{consecutive_same} consecutive same-size shots. "
|
||||
f"{longest_run} consecutive same-size shots. "
|
||||
f"Vary shot sizes between scenes for editorial rhythm."
|
||||
)
|
||||
|
||||
|
||||
37
tests/lib/test_variation_checker_runs.py
Normal file
37
tests/lib/test_variation_checker_runs.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""Regression test for check_scene_variation consecutive-run counting.
|
||||
|
||||
The "consecutive same-size shots" check summed every equal adjacent pair across
|
||||
the whole plan instead of measuring the longest actual run, so an editorially
|
||||
varied plan of separate 2-shot groups (wide,wide,cu,cu,med,med) falsely tripped
|
||||
a "3 consecutive same-size shots" violation.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from lib.variation_checker import check_scene_variation # noqa: E402
|
||||
|
||||
|
||||
def _scenes(sizes):
|
||||
return [{"shot_language": {"shot_size": s}} for s in sizes]
|
||||
|
||||
|
||||
def test_non_consecutive_same_size_pairs_do_not_trip_run_check():
|
||||
# Three separate 2-shot groups — longest run is 2, not 3.
|
||||
res = check_scene_variation(_scenes(["wide", "wide", "cu", "cu", "medium", "medium"]))
|
||||
assert not any("consecutive same-size" in v for v in res["violations"])
|
||||
|
||||
|
||||
def test_true_run_of_three_is_flagged():
|
||||
res = check_scene_variation(_scenes(["wide", "wide", "wide", "cu", "medium"]))
|
||||
assert any("3 consecutive same-size" in v for v in res["violations"])
|
||||
|
||||
|
||||
def test_unspecified_shots_do_not_form_a_run():
|
||||
res = check_scene_variation(
|
||||
_scenes(["unspecified", "unspecified", "unspecified", "unspecified"])
|
||||
)
|
||||
assert not any("consecutive same-size" in v for v in res["violations"])
|
||||
Reference in New Issue
Block a user