"""Deterministic renderer and analytic gold for a band checkpoint count.""" from __future__ import annotations import random from typing import Any from PIL import Image, ImageDraw, ImageFont RENDERER_VERSION = "band_checkpoint_count-0.1.0" CANVAS_SIZE = (1100, 650) PLOT_RECT = (110, 105, 990, 525) X_FRACTIONS = (0.12, 0.272, 0.424, 0.576, 0.728, 0.88) GRID_COLOR = (222, 228, 236) AXIS_COLOR = (63, 73, 88) PANEL_COLOR = (255, 255, 255) TITLE_COLOR = (26, 34, 46) SUBTITLE_COLOR = (82, 94, 111) CHECKPOINT_COLOR = (196, 204, 216) BLUE_EDGES = ( (34, 102, 194), (40, 118, 210), (50, 92, 181), (28, 126, 198), ) BLUE_FILLS = ( (210, 231, 250), (214, 235, 252), (218, 229, 249), (210, 237, 247), ) TRACE_COLORS = ( (18, 23, 31), (24, 29, 38), (30, 35, 44), (21, 27, 35), ) QUARANTINE_CLEARANCE = 0.045 def _font() -> ImageFont.ImageFont: return ImageFont.load_default() def _plot_point(index: int, value: float) -> tuple[int, int]: x0, y0, x1, y1 = PLOT_RECT x = round(x0 + X_FRACTIONS[index] * (x1 - x0)) y = round(y1 - value * (y1 - y0)) return x, y def sample_scene(seed: int) -> dict[str, Any]: """Sample a balanced six-checkpoint scene with independent visual nuisance fields.""" seed = int(seed) status_rng = random.Random(seed * 1009 + 17) geometry_rng = random.Random(seed * 9176 + 31) style_rng = random.Random(seed * 7919 + 53) count = seed % 7 statuses = [True] * count + [False] * (6 - count) status_rng.shuffle(statuses) near = seed % 11 in (0, 1) lower_values: list[float] = [] upper_values: list[float] = [] trace_values: list[float] = [] for inside in statuses: lower = geometry_rng.uniform(0.24, 0.52) height = geometry_rng.uniform(0.18, 0.27) upper = lower + height clearance = geometry_rng.uniform(0.025, 0.040) if near else geometry_rng.uniform(0.070, 0.115) if inside: trace = geometry_rng.uniform(lower + clearance, upper - clearance) elif geometry_rng.randrange(2) == 0: trace = lower - geometry_rng.uniform(clearance, 0.135) else: trace = upper + geometry_rng.uniform(clearance, 0.135) lower_values.append(round(lower, 6)) upper_values.append(round(upper, 6)) trace_values.append(round(trace, 6)) style_index = style_rng.randrange(len(BLUE_EDGES)) return { "trace_values": trace_values, "lower_values": lower_values, "upper_values": upper_values, "band_color": list(BLUE_EDGES[style_index]), "band_fill": list(BLUE_FILLS[style_index]), "trace_color": list(TRACE_COLORS[style_rng.randrange(len(TRACE_COLORS))]), "band_width": style_rng.randint(4, 6), "trace_width": style_rng.randint(4, 6), "marker_radius": style_rng.randint(8, 11), } def analytic_gold(scene: dict[str, Any]) -> str: """Return the visible count, using only the three rendered value arrays.""" flags = [ lower < value < upper for value, lower, upper in zip( scene["trace_values"], scene["lower_values"], scene["upper_values"] ) ] if len(flags) != 6: raise ValueError("a scene must contain six checkpoints") return str(sum(flags)) def margin(scene: dict[str, Any]) -> float: clearances = [] for value, lower, upper in zip( scene["trace_values"], scene["lower_values"], scene["upper_values"] ): clearances.append(min(abs(value - lower), abs(value - upper))) return float(min(clearances)) def is_quarantined(scene: dict[str, Any]) -> bool: return margin(scene) < QUARANTINE_CLEARANCE def _draw_dashed_vertical( draw: ImageDraw.ImageDraw, x: int, y0: int, y1: int, color: tuple[int, int, int] ) -> None: for start in range(y0 + 8, y1, 18): draw.line((x, start, x, min(start + 9, y1)), fill=color, width=2) def render(scene: dict[str, Any]) -> Image.Image: image = Image.new("RGB", CANVAS_SIZE, (248, 250, 253)) draw = ImageDraw.Draw(image) font = _font() x0, y0, x1, y1 = PLOT_RECT draw.text((52, 30), "trace checkpoints and a reference band", fill=TITLE_COLOR, font=font) draw.text( (52, 50), "Count black marker centers strictly between the two blue boundaries", fill=SUBTITLE_COLOR, font=font, ) draw.rounded_rectangle((42, 88, 1058, 575), radius=14, fill=(244, 247, 251), outline=(185, 194, 207), width=2) draw.rectangle(PLOT_RECT, fill=PANEL_COLOR, outline=AXIS_COLOR, width=2) for fraction in (0.2, 0.4, 0.6, 0.8): gx = round(x0 + fraction * (x1 - x0)) gy = round(y1 - fraction * (y1 - y0)) draw.line((gx, y0, gx, y1), fill=GRID_COLOR, width=1) draw.line((x0, gy, x1, gy), fill=GRID_COLOR, width=1) xs = [_plot_point(index, 0.0)[0] for index in range(6)] for x in xs: _draw_dashed_vertical(draw, x, y0 + 2, y1 - 2, CHECKPOINT_COLOR) upper_points = [_plot_point(index, value) for index, value in enumerate(scene["upper_values"])] lower_points = [_plot_point(index, value) for index, value in enumerate(scene["lower_values"])] fill_polygon = upper_points + list(reversed(lower_points)) draw.polygon(fill_polygon, fill=tuple(scene["band_fill"])) draw.line(upper_points, fill=tuple(scene["band_color"]), width=int(scene["band_width"])) draw.line(lower_points, fill=tuple(scene["band_color"]), width=int(scene["band_width"])) trace_points = [_plot_point(index, value) for index, value in enumerate(scene["trace_values"])] trace_color = tuple(scene["trace_color"]) draw.line(trace_points, fill=trace_color, width=int(scene["trace_width"])) radius = int(scene["marker_radius"]) for cx, cy in trace_points: draw.ellipse((cx - radius, cy - radius, cx + radius, cy + radius), fill=trace_color) draw.line((x0, y1, x1, y1), fill=AXIS_COLOR, width=2) draw.line((x0, y0, x0, y1), fill=AXIS_COLOR, width=2) draw.text((x0 - 7, y1 + 14), "0", fill=AXIS_COLOR, font=font) draw.text((x0 - 7, y0 - 14), "1", fill=AXIS_COLOR, font=font) for index, x in enumerate(xs, start=1): draw.text((x - 8, y1 + 14), f"T{index}", fill=AXIS_COLOR, font=font) draw.rectangle((58, 595, 78, 607), fill=tuple(scene["band_color"])) draw.text((86, 593), "blue band boundaries", fill=SUBTITLE_COLOR, font=font) draw.ellipse((295, 594, 307, 606), fill=trace_color) draw.text((316, 593), "black trace markers", fill=SUBTITLE_COLOR, font=font) return image def latent_symmetries(scene: dict[str, Any]) -> list[tuple[str, dict[str, Any]]]: """This parameterization has no hidden interchangeable label field.""" return []