Spaces:
Running
Running
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -249,7 +249,8 @@ def _factor_label(board: dict) -> str:
|
|
| 249 |
def merge_boards(boards: list) -> dict:
|
| 250 |
"""Pivot the per-factor boards into one wide board for a single table.
|
| 251 |
|
| 252 |
-
The Overall board (id "overall") supplies per-model license/size
|
|
|
|
| 253 |
composite score and `coverage` count are kept on the participant but not
|
| 254 |
displayed — ranking is dynamic, by whichever column the table is sorted on.
|
| 255 |
Every other board contributes one factor column keyed by its id, whose value
|
|
@@ -282,7 +283,7 @@ def merge_boards(boards: list) -> dict:
|
|
| 282 |
e = by_model.get(model)
|
| 283 |
if e is None:
|
| 284 |
e = {"rank": None, "model": model, "license": p.get("license"),
|
| 285 |
-
"sizeB": p.get("sizeB"), "notes": {},
|
| 286 |
"metrics": {"composite": None, "coverage": None}}
|
| 287 |
by_model[model] = e
|
| 288 |
order.append(model)
|
|
@@ -293,6 +294,7 @@ def merge_boards(boards: list) -> dict:
|
|
| 293 |
e["rank"] = p.get("rank")
|
| 294 |
e["license"] = p.get("license")
|
| 295 |
e["sizeB"] = p.get("sizeB")
|
|
|
|
| 296 |
e["metrics"]["composite"] = (p.get("metrics") or {}).get("score")
|
| 297 |
e["metrics"]["coverage"] = (p.get("metrics") or {}).get("coverage")
|
| 298 |
for b in factor_boards:
|
|
@@ -469,7 +471,12 @@ TABLE_CSS = """
|
|
| 469 |
/* a marker after a pill hangs beside it out of flow (absolute, no offsets =
|
| 470 |
static position), so starred pills stay centered in line with the column */
|
| 471 |
.ttslb .pill + .notemark { position:absolute; margin-left:3px; }
|
| 472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
.ttslb .nomatch { padding:24px 8px; color:var(--lb-ink-3); }
|
| 474 |
/* toolbar above each table: score-scale legend (left) + CSV download (right).
|
| 475 |
.tbl-box shrink-wraps to the table's width (capped at the card), so both
|
|
@@ -689,7 +696,10 @@ APP_JS = """
|
|
| 689 |
var lines = [heads.map(csvField).join(',')];
|
| 690 |
Array.prototype.forEach.call(table.tBodies[0].rows, function (r) {
|
| 691 |
lines.push(Array.prototype.map.call(r.cells, function (td) {
|
| 692 |
-
|
|
|
|
|
|
|
|
|
|
| 693 |
}).join(','));
|
| 694 |
});
|
| 695 |
var a = document.createElement('a');
|
|
@@ -789,9 +799,20 @@ def _row_html(p, heat_cols, primary_col, cov_col, rank_label, color_fn, marker_o
|
|
| 789 |
model_raw = str(p.get("model", ""))
|
| 790 |
lic_raw = (p.get("license") or "").strip() or "—"
|
| 791 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
cells = [
|
| 793 |
f"<td class='rank'>{rank_label}</td>",
|
| 794 |
-
|
| 795 |
f"<td class='lic'>{html.escape(lic_raw)}</td>",
|
| 796 |
]
|
| 797 |
# primary score + any extra factor columns: heatmapped pills. A participant
|
|
@@ -872,10 +893,16 @@ def render_board_html(board: dict, lic: str = "all", fname: str = "board") -> st
|
|
| 872 |
ranked, unranked = list(parts), []
|
| 873 |
|
| 874 |
# Footnote markers: one symbol per distinct note among the visible cells — a
|
| 875 |
-
# note
|
| 876 |
-
#
|
| 877 |
-
|
|
|
|
|
|
|
| 878 |
marker_of = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 879 |
for c in value_cols:
|
| 880 |
for p in parts:
|
| 881 |
note = (p.get("notes") or {}).get(c["field"])
|
|
|
|
| 249 |
def merge_boards(boards: list) -> dict:
|
| 250 |
"""Pivot the per-factor boards into one wide board for a single table.
|
| 251 |
|
| 252 |
+
The Overall board (id "overall") supplies per-model license/size and any
|
| 253 |
+
provider-level `note` (rendered as a marker on the model name); its rank,
|
| 254 |
composite score and `coverage` count are kept on the participant but not
|
| 255 |
displayed — ranking is dynamic, by whichever column the table is sorted on.
|
| 256 |
Every other board contributes one factor column keyed by its id, whose value
|
|
|
|
| 283 |
e = by_model.get(model)
|
| 284 |
if e is None:
|
| 285 |
e = {"rank": None, "model": model, "license": p.get("license"),
|
| 286 |
+
"sizeB": p.get("sizeB"), "note": None, "notes": {},
|
| 287 |
"metrics": {"composite": None, "coverage": None}}
|
| 288 |
by_model[model] = e
|
| 289 |
order.append(model)
|
|
|
|
| 294 |
e["rank"] = p.get("rank")
|
| 295 |
e["license"] = p.get("license")
|
| 296 |
e["sizeB"] = p.get("sizeB")
|
| 297 |
+
e["note"] = p.get("note") # provider-level caveat -> marker on the name
|
| 298 |
e["metrics"]["composite"] = (p.get("metrics") or {}).get("score")
|
| 299 |
e["metrics"]["coverage"] = (p.get("metrics") or {}).get("coverage")
|
| 300 |
for b in factor_boards:
|
|
|
|
| 471 |
/* a marker after a pill hangs beside it out of flow (absolute, no offsets =
|
| 472 |
static position), so starred pills stay centered in line with the column */
|
| 473 |
.ttslb .pill + .notemark { position:absolute; margin-left:3px; }
|
| 474 |
+
/* provider-level markers ride superscript after the model name (.notemark is
|
| 475 |
+
already position:relative for its tooltip, so a top offset lifts it) */
|
| 476 |
+
.ttslb td.prov .notemark { margin-left:2px; font-size:9.5px; top:-0.45em; }
|
| 477 |
+
.ttslb .footnotes { margin-top:10px; color:var(--lb-ink-2); font-size:12.5px; line-height:1.7; text-align:left; }
|
| 478 |
+
/* the symbol leading each footnote line gets a slight bump so a lone "*" reads */
|
| 479 |
+
.ttslb .footnotes .notemark { font-size:1.15em; margin-right:2px; }
|
| 480 |
.ttslb .nomatch { padding:24px 8px; color:var(--lb-ink-3); }
|
| 481 |
/* toolbar above each table: score-scale legend (left) + CSV download (right).
|
| 482 |
.tbl-box shrink-wraps to the table's width (capped at the card), so both
|
|
|
|
| 696 |
var lines = [heads.map(csvField).join(',')];
|
| 697 |
Array.prototype.forEach.call(table.tBodies[0].rows, function (r) {
|
| 698 |
lines.push(Array.prototype.map.call(r.cells, function (td) {
|
| 699 |
+
if (td.hasAttribute('data-v')) return csvField(td.getAttribute('data-v'));
|
| 700 |
+
var c = td.cloneNode(true); // footnote markers stay out of the CSV
|
| 701 |
+
c.querySelectorAll('.notemark').forEach(function (n) { n.remove(); });
|
| 702 |
+
return csvField(c.textContent.trim());
|
| 703 |
}).join(','));
|
| 704 |
});
|
| 705 |
var a = document.createElement('a');
|
|
|
|
| 799 |
model_raw = str(p.get("model", ""))
|
| 800 |
lic_raw = (p.get("license") or "").strip() or "—"
|
| 801 |
|
| 802 |
+
# a provider-level note (a caveat about the model itself, e.g. "this name is
|
| 803 |
+
# a cascade alias") marks the model name rather than any one factor cell
|
| 804 |
+
pnote = p.get("note")
|
| 805 |
+
pmark = (marker_of or {}).get(pnote) if pnote else None
|
| 806 |
+
if pmark:
|
| 807 |
+
ptip = html.escape(pnote, quote=True)
|
| 808 |
+
prov_cell = (f"<td class='prov notecell'>{html.escape(model_raw)}"
|
| 809 |
+
f"<span class='notemark' data-tip=\"{ptip}\">{pmark}</span></td>")
|
| 810 |
+
else:
|
| 811 |
+
prov_cell = f"<td class='prov'>{html.escape(model_raw)}</td>"
|
| 812 |
+
|
| 813 |
cells = [
|
| 814 |
f"<td class='rank'>{rank_label}</td>",
|
| 815 |
+
prov_cell,
|
| 816 |
f"<td class='lic'>{html.escape(lic_raw)}</td>",
|
| 817 |
]
|
| 818 |
# primary score + any extra factor columns: heatmapped pills. A participant
|
|
|
|
| 893 |
ranked, unranked = list(parts), []
|
| 894 |
|
| 895 |
# Footnote markers: one symbol per distinct note among the visible cells — a
|
| 896 |
+
# provider-level note marks the model name (a caveat about the model itself),
|
| 897 |
+
# a note on an empty cell explains the gap, and a note on a valued cell flags
|
| 898 |
+
# a caveat (e.g. r reported as 0 where zero variance left it undefined).
|
| 899 |
+
# Provider notes are collected first so the leftmost column's symbols lead.
|
| 900 |
+
_MARKS = ("*", "††", "‡‡", "§§", "‖‖", "¶¶")
|
| 901 |
marker_of = {}
|
| 902 |
+
for p in parts:
|
| 903 |
+
note = p.get("note")
|
| 904 |
+
if note and note not in marker_of:
|
| 905 |
+
marker_of[note] = _MARKS[len(marker_of) % len(_MARKS)]
|
| 906 |
for c in value_cols:
|
| 907 |
for p in parts:
|
| 908 |
note = (p.get("notes") or {}).get(c["field"])
|