Spaces:
Running on Zero
Running on Zero
Download src/spatial_jev/numeric_tasks.py from hugging-apps/mjev-spatial: direct link, hf CLI and curl.
- Browser
- Download file 3.38 kB
-
https://huggingface.co/spaces/hugging-apps/mjev-spatial/resolve/main/src/spatial_jev/numeric_tasks.py
- Command line
-
hf download hf://spaces/hugging-apps/mjev-spatial/src/spatial_jev/numeric_tasks.py
-
curl -L -o numeric_tasks.py https://huggingface.co/spaces/hugging-apps/mjev-spatial/resolve/main/src/spatial_jev/numeric_tasks.py
3.38 kB
| """Input-selected numeric codebooks; never interpret counts or degrees as meters.""" | |
| import math | |
| COUNT_CODEBOOK = {"version": "integer-32x32-v1", "unit": "count", "fine_bins": 32, | |
| "maximum": 1023} | |
| ANGLE_CODEBOOK = {"version": "degrees-30x32-v1", "unit": "deg", "fine_bins": 32, | |
| "edges_m": list(range(0, 361, 30)), "overflow_representative_m": 360.0} | |
| # edges_m is the historical controller's internal key, not the physical unit. | |
| # Public answer spaces, prompts, validators and decoded units remain explicit. | |
| def codebook_for(inp, metric): | |
| unit = inp["answer_space"].get("unit", "m") | |
| if unit == "m": | |
| return metric | |
| if unit == "count": | |
| return COUNT_CODEBOOK | |
| if unit == "deg": | |
| return ANGLE_CODEBOOK | |
| raise ValueError(f"Unsupported numeric unit: {unit}") | |
| def numeric_path(value, codebook): | |
| from .hierarchy import scalar_path | |
| if codebook.get("unit", "m") != "count": | |
| if codebook.get("unit") == "deg" and not 0 <= value <= 360: | |
| raise ValueError("Angle outside [0, 360]") | |
| return scalar_path(value, codebook) | |
| if isinstance(value, bool) or not math.isfinite(value) or int(value) != value or not 0 <= value <= 1023: | |
| raise ValueError("Count outside integer codebook [0, 1023]") | |
| return [int(value) // 32, int(value) % 32] | |
| def numeric_done(path, codebook): | |
| return len(path) == 2 or (codebook.get("unit", "m") != "count" and path[0] in (0, len(codebook["edges_m"]))) | |
| def decode_numeric(path, codebook): | |
| from .hierarchy import decode_scalar | |
| if codebook.get("unit", "m") != "count": | |
| return decode_scalar(path, codebook) | |
| if len(path) != 2 or any(not 0 <= n < 32 for n in path): | |
| raise ValueError("Invalid integer decision path") | |
| return 32 * path[0] + path[1] | |
| def numeric_prompt(inp, root, codebook): | |
| """Non-metric prompts. Metric prompts intentionally keep their old exact bytes.""" | |
| if codebook["unit"] == "count": | |
| options = ([f"count {32*i} through {32*i+31} (inclusive)" for i in range(32)] | |
| if root is None else [f"count exactly {32*root+i}" for i in range(32)]) | |
| instruction = "Answer the counting question. Select the integer count or inclusive count range." | |
| else: | |
| from .hierarchy import scalar_interval | |
| edges = codebook["edges_m"] | |
| if root is None: | |
| options = ["exactly zero degrees"] | |
| options += [f"{lo:g} to {hi:g} degrees" for lo, hi in zip(edges, edges[1:])] | |
| options[1] = "greater than zero and less than 30 degrees" | |
| options += ["greater than 360 degrees (out of supported range)"] | |
| else: | |
| lo, hi = scalar_interval(root, codebook) | |
| step = (hi - lo) / codebook["fine_bins"] | |
| options = [f"{lo+i*step:.6g} to {lo+(i+1)*step:.6g} degrees" for i in range(32)] | |
| instruction = ("Estimate the angle in degrees, preserving the reference frame and rotation " | |
| "direction specified in the question. Ranges include the lower endpoint and " | |
| "exclude the upper, except that 360 is included. Exact zero has its own class.") | |
| return (f"Question: {inp['question']}\n{instruction}\nOptions:\n" | |
| + "\n".join(f"{i+1}. {s}" for i, s in enumerate(options)) | |
| + "\nSelect exactly one option."), len(options) | |