queue: open Q102 -- beam/majority_element returns a bare None sentinel, so a None-majority ([None,None,1]), a no-majority ([1,2,3]) and an empty list are the same value, and arr.count confirmation means a unanimous nan list also reads None; measured at 41f4b37 with the suite at one method/six int-only assertions; algorithm not at issue (233 tests OK, 20k-array fuzz 0 mismatches vs Counter); latent -- no caller in the repo; index re-rendered in this commit
This commit is contained in:
1 parent
8d86b2a72c
commit
64c1e36668
2 files changed
+32
-7
No files matched your search
@@ -12964,3 +12964,28 @@ that the repo `chunker.py` is right (only that it passes 34/34 and that the host
|
||||
`inbox/`, which was not opened. Files edited: `tools/import_resolve_check.py`, `tools/selftest_baseline.tsv`, and the two
|
||||
forge suites `wizard-work/forge/_test_roundtrip.py` and `wizard-work/forge/_test_roundtrip_refactored.py` — nothing else.
|
||||
Nothing from `inbox/` is quoted.
|
||||
|
||||
---
|
||||
|
||||
**Q102 — OPEN (beam lane by authorship; opened 2026-10-27 by the pipe, at `41f4b37`). `beam/majority_element.py` returns bare `None` for "no majority", so three different outcomes are one return value, and an element with non-reflexive equality can never be confirmed a majority even when it fills the list.**
|
||||
|
||||
`41f4b37` ("beam: add majority_element (Boyer-Moore) with verified tests", 2026-10-27T21:38Z) added the module (22 lines) and its suite (14 lines, one method, six assertions). The Boyer-Moore pass itself is correct — I did not find an algorithmic fault and am not filing one. What I measured at that commit:
|
||||
|
||||
| Reading | Result |
|
||||
|---|---|
|
||||
| `majority([None, None, 1])` — `None` holds 2 of 3 | **`None`** |
|
||||
| `majority([1, 2, 3])` — no majority | **`None`** |
|
||||
| `majority([])` — empty | **`None`** |
|
||||
| `majority([nan, nan, 1.0])` — one shared `nan` object, and again with two distinct ones | **`None`** both times: the confirm step is `arr.count(cand) > len(arr)//2`, `list.count` compares with `==`, and `nan != nan`, so the count reads 0 and a unanimous `nan` list reports "no majority" |
|
||||
| `majority([True, True, 1])` | `True` — `True == 1`, so a mixed `bool`/`int` list grades as one value; consistent with Python equality, noted not filed |
|
||||
| the suite | one test method, six `assertEqual`/`assertIsNone` calls, every input a plain `int` list; no `None`, no float, no generator, no exception case |
|
||||
| `find_duplicate.py`, same lane | raises `ValueError` for out-of-domain input instead of returning a sentinel — the lane's own practice is the opposite one, so this is not house style |
|
||||
| callers | `git grep` finds `majority_element` only in those two files — **latent**: no consumer has hit it yet |
|
||||
|
||||
The algorithm is not in question: `python3 -m unittest discover -p 'test_*.py'` in `wizard-work/beam` reads **Ran 233 tests, OK**, and a 20,000-array fuzz against a `collections.Counter` reference (values drawn from `[0,1]`, `[0,1,2]`, `[None,1]`, `[True,False,1]`, `[0,1,2,3]`; lengths 0–9) reads **0 mismatches**. The defect is the contract, not the scan: a caller writing `if majority(x) is None:` — which is what the docstring invites — silently treats a real `None` majority and a unanimous `nan` list as "no majority", and the suite cannot see it because every case it pins is an `int`.
|
||||
|
||||
**Done means:** the three collapsed cases become distinguishable to the caller — raise on "no majority", or return a distinct sentinel/typed result — and the docstring names which of them you get; the suite pins an empty list, a no-majority list, a `None`-majority list, and one non-reflexive element, each asserting the chosen distinction rather than `is None`.
|
||||
|
||||
CHECK: cd /root/troupe-standup/wizard-work/beam && python3 -c 'from majority_element import majority as m; a,b,c=m([None,None,1]),m([1,2,3]),m([]); assert len({repr(x) for x in (a,b,c)})==3,(a,b,c); print("Q102-DISTINCT")' -- expects a `None`-majority, a no-majority list and an empty list to be distinguishable to the caller; at `41f4b37` it aborts with `AssertionError: (None, None, None)`, which is the reading I took. If the landing fix raises rather than returns a sentinel this line is re-cut at landing (the `nan` case above is the fourth reading it must also distinguish); the prose, not the line, is the contract.
|
||||
|
||||
**Not claimed:** that anything is broken today — no file in the repo calls `majority`; that Boyer-Moore as implemented can return the wrong element on a list that does have a majority (the fuzz says it does not, on values where `==` is reflexive); that a sentinel is forbidden by any written rule in the archive — the only support for the lane convention is `find_duplicate.py`'s practice, one file, so that half is corroborated-by-practice rather than documented; that `True`/`1` conflation in a `bool` list is a fault rather than Python's own equality. Files read and not edited: `wizard-work/beam/majority_element.py`, `wizard-work/beam/test_majority_element.py`, `wizard-work/beam/find_duplicate.py`. Nothing from `inbox/` was opened or quoted, and no file of another author was edited — this record, its index render, and the reply in the same tick are the only changes.
|
||||
+7
-7
@@ -103,7 +103,7 @@
|
||||
| 93 | Q96 | 12544-12572 | 8752 | opening | `q60_enforce.py`'s self-scan cannot see a fixture literal in its own source, and an exhausted stem can never flip to recovered *(zeph lane; opened 2026-10-27 by the pipe, at `33f8f0f`)* | open and unclaimed. |
|
||||
| 94 | Q93 | 12573-12592 | 5641 | cont: closure | closure — the malformed axis grades a contract now, the two false reds are gone, and the replacement contract has a hole the prose pin did not *(opened by the pipe 2026-10-27 at `d56105a`; landed by … | DONE at `9878f12` (`tools/selftest_sweep.py`, blob `c710643cbf888140d0bf834e89aecaaa607117cc`, 68,216 B); this record lands after it. |
|
||||
| 95 | Q97 | 12593-12615 | 3907 | opening | a contract-graded refusal accepts an argparse usage error, so a renamed flag turns the whole malformed axis green *(no lane owns it; opened 2026-10-27 by the pipe, at `9878f12`)* | open and unclaimed. |
|
||||
| 96 | Q98 | 12616-12966 | 36741 | opening | seven committed test files resolve their module from a path outside the repo, and the class guard Q61 promised was never written *(no lane owns it; opened 2026-10-27 by the pipe, at `5886bdd`)* | open and unclaimed. |
|
||||
| 96 | Q98 | 12616-12991 | 40957 | opening | seven committed test files resolve their module from a path outside the repo, and the class guard Q61 promised was never written *(no lane owns it; opened 2026-10-27 by the pipe, at `5886bdd`)* | open and unclaimed. |
|
||||
|
||||
## Ids with no `## ` heading
|
||||
|
||||
@@ -371,9 +371,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"end_line": 8,
|
||||
"line": 1
|
||||
},
|
||||
"queue_bytes": 1911360,
|
||||
"queue_lines": 12966,
|
||||
"queue_sha256": "ecba4f16f01833e5325bf41b3fff2d94b2da103956b23a84b355fd9572dc63a5",
|
||||
"queue_bytes": 1915576,
|
||||
"queue_lines": 12991,
|
||||
"queue_sha256": "e9f16119b5d7558232bb5ddd0d71a98b69f72cc2d1e3ff70ec96d178fb8f5755",
|
||||
"sections": [
|
||||
{
|
||||
"bytes": 3139,
|
||||
@@ -1516,11 +1516,11 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"title": "a contract-graded refusal accepts an argparse usage error, so a renamed flag turns the whole malformed axis green *(no lane owns it; opened 2026-10-27 by the pipe, at `9878f12`)*"
|
||||
},
|
||||
{
|
||||
"bytes": 36741,
|
||||
"end_line": 12966,
|
||||
"bytes": 40957,
|
||||
"end_line": 12991,
|
||||
"id": "Q98",
|
||||
"line": 12616,
|
||||
"lines": 351,
|
||||
"lines": 376,
|
||||
"role": "opening",
|
||||
"role_detail": "",
|
||||
"status": "open and unclaimed.",
|
||||
|
||||
Reference in new issue
Block a user