Record the axes that were produced; rank only complete entries
Browse filesAn entry missing one axis was previously left with no score at all, discarding figures we already had. The axes that were produced are now recorded and shown against their own maximum. Rank is withheld while any axis is outstanding - a partial total cannot be set beside a complete one - and the row states what the entry needs.
- app.py +8 -5
- index.html +13 -12
app.py
CHANGED
|
@@ -310,8 +310,10 @@ def _leaderboard_body(season):
|
|
| 310 |
anchors = _anchors(season)
|
| 311 |
merged = rows + anchors
|
| 312 |
# μ μκ° μλ κ²μ 맨 λ€λ‘. κ·Έ μμμλ λΈ μμλ₯Ό μ§ν¨λ€.
|
|
|
|
|
|
|
| 313 |
merged.sort(key=lambda e: (e.get("tier", 1),
|
| 314 |
-
|
| 315 |
-(e.get("total") if e.get("total") is not None else 0),
|
| 316 |
e.get("submitted_at") or 0))
|
| 317 |
n = 0
|
|
@@ -319,9 +321,9 @@ def _leaderboard_body(season):
|
|
| 319 |
for e in merged:
|
| 320 |
comp = e.get("composition") or {}
|
| 321 |
e["division"] = division_of(comp)
|
| 322 |
-
# λ±μλ **
|
| 323 |
-
#
|
| 324 |
-
unscored = e.get("total") is None
|
| 325 |
if e.get("is_anchor") or e.get("tier", 1) != 1 or unscored:
|
| 326 |
e["rank"] = None # κΈ°μ€λ¬Όμ§μ μ²λλ₯Ό νμν λΏ λ±μλ₯Ό κ°μ§ μλλ€
|
| 327 |
e["div_rank"] = None
|
|
@@ -338,7 +340,8 @@ def _leaderboard_body(season):
|
|
| 338 |
continue
|
| 339 |
tally[e["division"]] = tally.get(e["division"], 0) + 1
|
| 340 |
n_held = sum(1 for e in merged
|
| 341 |
-
if not e.get("is_anchor")
|
|
|
|
| 342 |
return {"season": seasons.public(season), "entries": merged,
|
| 343 |
"divisions": tally,
|
| 344 |
"counts": {"scored": len(rows) - n_held, "held": n_held,
|
|
|
|
| 310 |
anchors = _anchors(season)
|
| 311 |
merged = rows + anchors
|
| 312 |
# μ μκ° μλ κ²μ 맨 λ€λ‘. κ·Έ μμμλ λΈ μμλ₯Ό μ§ν¨λ€.
|
| 313 |
+
# μ μΆμ΄ μ±μμ§ κ²λΆν°, κ·Έ μμμ μ΄μ μ. μΆμ΄ λΉ κ²μ λ€λ‘ - μ΄μ μ΄ μμ΄λ
|
| 314 |
+
# λ§μ μ΄ λ¬λΌ κ°μ μ€μ μΈμΈ μ μλ€.
|
| 315 |
merged.sort(key=lambda e: (e.get("tier", 1),
|
| 316 |
+
1 if (e.get("total") is None or e.get("held_axes")) else 0,
|
| 317 |
-(e.get("total") if e.get("total") is not None else 0),
|
| 318 |
e.get("submitted_at") or 0))
|
| 319 |
n = 0
|
|
|
|
| 321 |
for e in merged:
|
| 322 |
comp = e.get("composition") or {}
|
| 323 |
e["division"] = division_of(comp)
|
| 324 |
+
# λ±μλ **μ μΆμ΄ μ±μμ§ κ²**μλ§ μ€λ€. μΆμ΄ νλλΌλ λΉλ©΄ λ§μ μ΄ λ¬λΌ μ΄μ μ
|
| 325 |
+
# λλν μΈμΈ μ μλ€ - μ μλ λ¨κΈ°λ μμμλ λ£μ§ μλλ€.
|
| 326 |
+
unscored = e.get("total") is None or bool(e.get("held_axes"))
|
| 327 |
if e.get("is_anchor") or e.get("tier", 1) != 1 or unscored:
|
| 328 |
e["rank"] = None # κΈ°μ€λ¬Όμ§μ μ²λλ₯Ό νμν λΏ λ±μλ₯Ό κ°μ§ μλλ€
|
| 329 |
e["div_rank"] = None
|
|
|
|
| 340 |
continue
|
| 341 |
tally[e["division"]] = tally.get(e["division"], 0) + 1
|
| 342 |
n_held = sum(1 for e in merged
|
| 343 |
+
if not e.get("is_anchor")
|
| 344 |
+
and (e.get("total") is None or e.get("held_axes")))
|
| 345 |
return {"season": seasons.public(season), "entries": merged,
|
| 346 |
"divisions": tally,
|
| 347 |
"counts": {"scored": len(rows) - n_held, "held": n_held,
|
index.html
CHANGED
|
@@ -296,14 +296,14 @@ const T = {
|
|
| 296 |
["λ¦¬ν¬ μ΄λ κ²½λ‘","μ μκ° μλλΌ <b>μ°Έκ° μ‘°κ±΄</b>μ
λλ€. 리ν¬μ΄ μ§λκ° κ΄ν΅ κ²½λ‘κ° μμΌλ©΄ μ μλμ§ μμ΅λλ€."]],
|
| 297 |
limits:(L)=>`μ μΆ μ ν β λ¦¬ν¬ νμ Β· κΈ°μ½ μ‘°μ± μμ μ ${L.max_atoms}κ° μ΄ν Β· μμ 6μ’
μ΄ν.
|
| 298 |
κ°μ λ¬Όμ§μ μ μλ°°λ‘ λ°κΏ λ€μ λ΄λ©΄ κ°μ μ μΆλ‘ μ²λ¦¬λ©λλ€.`,
|
| 299 |
-
detail_h:"μ±μ
|
| 300 |
board_h:"μμν",
|
| 301 |
boardnote:`<b>κΈ°μ€λ¬Όμ§(λ
Έλ ν)</b>μ μ μλ₯Ό λ°λ λ±μλ₯Ό κ°μ§ μμ΅λλ€. μ€μ λ‘ μ°μ΄λ μ ν΄μ§μ΄ λͺ μ μΈμ§
|
| 302 |
λμΌλ‘ λΉκ΅νμλΌκ³ λ£μμ΅λλ€.<br>
|
| 303 |
λΉκ³΅κ° μ μΆμ μ‘°μ±μ κ°λ¦¬κ³ <b>μμ μ’
λ₯λ§</b> νμν©λλ€. μλ³Έμ λΉκ³΅κ°λ‘ 보κ΄λ©λλ€.<br>
|
| 304 |
-
<b>ꡬ쑰 νμ Β·
|
| 305 |
-
|
| 306 |
-
λλΆλΆμ
|
| 307 |
μ΄ μ λͺ©μ λλ¬ μ λ ¬ν μ μμ΅λλ€.`,
|
| 308 |
submit_h:"μ μΆ",
|
| 309 |
l_formula:"μ‘°μ± (ννμ)", l_name:"νμ ID (μ΄λ¦Β·μμΒ·λλ€μ)", l_model:"μ¬μ© λͺ¨λΈλͺ
(μ ν)",
|
|
@@ -330,7 +330,7 @@ const T = {
|
|
| 330 |
need:"μ‘°μ±κ³Ό νμ IDλ₯Ό μ
λ ₯ν΄ μ£ΌμΈμ.",
|
| 331 |
hold:"λ―Έμ°μΆ",
|
| 332 |
holds:{need_structure:"ꡬ쑰 νμ", no_reference:"λΉκ΅μλ£ λΆμ‘±", no_value:"μ°μΆ λΆκ°"},
|
| 333 |
-
holdnote:"
|
| 334 |
},
|
| 335 |
en:{
|
| 336 |
sub:"Open problems, worked on together β materials discovery anyone can join",
|
|
@@ -382,10 +382,10 @@ const T = {
|
|
| 382 |
boardnote:`<b>Reference materials (amber rows)</b> are scored but hold no rank. They are there so you can see
|
| 383 |
where materials in actual use land.<br>
|
| 384 |
Private entries show <b>elements only</b>; the composition is held back.<br>
|
| 385 |
-
<b>Structure needed / no
|
| 386 |
-
|
| 387 |
-
<b>
|
| 388 |
-
|
| 389 |
Click a column header to sort.`,
|
| 390 |
submit_h:"Submit",
|
| 391 |
l_formula:"Composition (formula)", l_name:"Display ID (name, affiliation or handle)",
|
|
@@ -413,7 +413,7 @@ const T = {
|
|
| 413 |
need:"Please enter a composition and a display ID.",
|
| 414 |
hold:"not scored",
|
| 415 |
holds:{need_structure:"structure needed", no_reference:"no reference data", no_value:"no value"},
|
| 416 |
-
holdnote:"
|
| 417 |
}
|
| 418 |
};
|
| 419 |
|
|
@@ -768,7 +768,7 @@ function render(){
|
|
| 768 |
{ const bn = $("#t_boardnote"); if(bn) bn.innerHTML = d.boardnote + "<br>" + d.divnote; }
|
| 769 |
$("#rows").innerHTML = rows.length ? rows.map(e=>{
|
| 770 |
const a = e.axes||{};
|
| 771 |
-
const unscored = e.total == null
|
| 772 |
const cls = [e.is_anchor?"anchor":"", unscored?"held":""].join(" ").trim();
|
| 773 |
const who = e.is_anchor ? esc(e.display_name)
|
| 774 |
: (e.hf_user ? hfProfile(e.hf_user)
|
|
@@ -780,7 +780,8 @@ function render(){
|
|
| 780 |
const dt = e.submitted_at ? new Date(e.submitted_at*1000).toISOString().slice(0,10) : "";
|
| 781 |
const hk = e.hold_kind && d.holds[e.hold_kind];
|
| 782 |
const tot = e.total==null ? `<span class="pill warn">${esc(hk || d.hold)}</span>`
|
| 783 |
-
: `${e.total.toFixed(1)}
|
|
|
|
| 784 |
const has = (e.detail && Object.keys(e.detail).length) || (unscored && e.gate);
|
| 785 |
return `<tr class="${cls}${has?" pick":""}"${has?` data-i="${e.candidate_id}"`:""}>
|
| 786 |
<td class="num">${(DIV==="all" ? e.rank : e.div_rank) ?? "β"}</td>
|
|
|
|
| 296 |
["λ¦¬ν¬ μ΄λ κ²½λ‘","μ μκ° μλλΌ <b>μ°Έκ° μ‘°κ±΄</b>μ
λλ€. 리ν¬μ΄ μ§λκ° κ΄ν΅ κ²½λ‘κ° μμΌλ©΄ μ μλμ§ μμ΅λλ€."]],
|
| 297 |
limits:(L)=>`μ μΆ μ ν β λ¦¬ν¬ νμ Β· κΈ°μ½ μ‘°μ± μμ μ ${L.max_atoms}κ° μ΄ν Β· μμ 6μ’
μ΄ν.
|
| 298 |
κ°μ λ¬Όμ§μ μ μλ°°λ‘ λ°κΏ λ€μ λ΄λ©΄ κ°μ μ μΆλ‘ μ²λ¦¬λ©λλ€.`,
|
| 299 |
+
detail_h:"μ±μ λ΄μ",
|
| 300 |
board_h:"μμν",
|
| 301 |
boardnote:`<b>κΈ°μ€λ¬Όμ§(λ
Έλ ν)</b>μ μ μλ₯Ό λ°λ λ±μλ₯Ό κ°μ§ μμ΅λλ€. μ€μ λ‘ μ°μ΄λ μ ν΄μ§μ΄ λͺ μ μΈμ§
|
| 302 |
λμΌλ‘ λΉκ΅νμλΌκ³ λ£μμ΅λλ€.<br>
|
| 303 |
λΉκ³΅κ° μ μΆμ μ‘°μ±μ κ°λ¦¬κ³ <b>μμ μ’
λ₯λ§</b> νμν©λλ€. μλ³Έμ λΉκ³΅κ°λ‘ 보κ΄λ©λλ€.<br>
|
| 304 |
+
<b>ꡬ쑰 νμ Β· λΉκ΅μλ£ λΆμ‘±</b>λ μ±μ μκ±΄μ΄ κ°μΆ°μ§μ§ μμ μνμ
λλ€. 0μ μΌλ‘ κΈ°λ‘νμ§
|
| 305 |
+
μκ³ λ±μλ λ§€κΈ°μ§ μμ΅λλ€ β μ¬μ§ μμ κ²μ μ±μ μΌλ‘ μ μ§ μκΈ° λλ¬Έμ
λλ€.
|
| 306 |
+
<b>λλΆλΆμ ꡬ쑰 νμΌ(CIF)μ 첨λΆν΄ λ€μ μ μΆνμλ©΄ μ±μ λ©λλ€.</b> νμ λλ₯΄λ©΄ νμν κ²μ΄ λμ΅λλ€.<br>
|
| 307 |
μ΄ μ λͺ©μ λλ¬ μ λ ¬ν μ μμ΅λλ€.`,
|
| 308 |
submit_h:"μ μΆ",
|
| 309 |
l_formula:"μ‘°μ± (ννμ)", l_name:"νμ ID (μ΄λ¦Β·μμΒ·λλ€μ)", l_model:"μ¬μ© λͺ¨λΈλͺ
(μ ν)",
|
|
|
|
| 330 |
need:"μ‘°μ±κ³Ό νμ IDλ₯Ό μ
λ ₯ν΄ μ£ΌμΈμ.",
|
| 331 |
hold:"λ―Έμ°μΆ",
|
| 332 |
holds:{need_structure:"ꡬ쑰 νμ", no_reference:"λΉκ΅μλ£ λΆμ‘±", no_value:"μ°μΆ λΆκ°"},
|
| 333 |
+
holdnote:"μλ μ건μ κ°μΆ° λ€μ μ μΆνμλ©΄ μ±μ λ©λλ€."
|
| 334 |
},
|
| 335 |
en:{
|
| 336 |
sub:"Open problems, worked on together β materials discovery anyone can join",
|
|
|
|
| 382 |
boardnote:`<b>Reference materials (amber rows)</b> are scored but hold no rank. They are there so you can see
|
| 383 |
where materials in actual use land.<br>
|
| 384 |
Private entries show <b>elements only</b>; the composition is held back.<br>
|
| 385 |
+
<b>Structure needed / no reference data</b> means the requirements for scoring are not yet met.
|
| 386 |
+
Nothing is recorded as zero and no rank is assigned - an unmeasured entry is not given a standing.
|
| 387 |
+
<b>Most cases are scored once a structure file (CIF) is attached and the entry resubmitted.</b>
|
| 388 |
+
Click the row to see what is required.<br>
|
| 389 |
Click a column header to sort.`,
|
| 390 |
submit_h:"Submit",
|
| 391 |
l_formula:"Composition (formula)", l_name:"Display ID (name, affiliation or handle)",
|
|
|
|
| 413 |
need:"Please enter a composition and a display ID.",
|
| 414 |
hold:"not scored",
|
| 415 |
holds:{need_structure:"structure needed", no_reference:"no reference data", no_value:"no value"},
|
| 416 |
+
holdnote:"Meet the requirement below and resubmit; the entry will then be scored."
|
| 417 |
}
|
| 418 |
};
|
| 419 |
|
|
|
|
| 768 |
{ const bn = $("#t_boardnote"); if(bn) bn.innerHTML = d.boardnote + "<br>" + d.divnote; }
|
| 769 |
$("#rows").innerHTML = rows.length ? rows.map(e=>{
|
| 770 |
const a = e.axes||{};
|
| 771 |
+
const unscored = !e.is_anchor && (e.total == null || (e.held_axes||[]).length > 0);
|
| 772 |
const cls = [e.is_anchor?"anchor":"", unscored?"held":""].join(" ").trim();
|
| 773 |
const who = e.is_anchor ? esc(e.display_name)
|
| 774 |
: (e.hf_user ? hfProfile(e.hf_user)
|
|
|
|
| 780 |
const dt = e.submitted_at ? new Date(e.submitted_at*1000).toISOString().slice(0,10) : "";
|
| 781 |
const hk = e.hold_kind && d.holds[e.hold_kind];
|
| 782 |
const tot = e.total==null ? `<span class="pill warn">${esc(hk || d.hold)}</span>`
|
| 783 |
+
: `${e.total.toFixed(1)}<span class="sub" style="font-size:11px"> /${e.total_max||100}</span>`
|
| 784 |
+
+ (unscored ? ` <span class="pill warn">${esc(hk || d.hold)}</span>` : "");
|
| 785 |
const has = (e.detail && Object.keys(e.detail).length) || (unscored && e.gate);
|
| 786 |
return `<tr class="${cls}${has?" pick":""}"${has?` data-i="${e.candidate_id}"`:""}>
|
| 787 |
<td class="num">${(DIV==="all" ? e.rank : e.div_rank) ?? "β"}</td>
|