SeaWolf-AI commited on
Commit
2962494
Β·
verified Β·
1 Parent(s): 7fb50d4

Record the axes that were produced; rank only complete entries

Browse files

An 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.

Files changed (2) hide show
  1. app.py +8 -5
  2. 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
- 0 if e.get("total") is not None else 1,
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") and e.get("total") is None)
 
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>ꡬ쑰 ν•„μš” Β· μ‚°μΆœ λΆˆκ°€</b>λŠ” 저희가 값을 κ΅¬ν•˜μ§€ λͺ»ν•œ κ²ƒμž…λ‹ˆλ‹€ β€” 제좜물의 λ¬Έμ œκ°€ μ•„λ‹ˆλ―€λ‘œ
305
- 0점이 μ•„λ‹ˆλΌ λ“±μˆ˜ 없이 ν‘œμ—λ§Œ λ‚¨μŠ΅λ‹ˆλ‹€. <b>κΈ°λ‹€λ¦°λ‹€κ³  풀리지 μ•ŠμŠ΅λ‹ˆλ‹€.</b>
306
- λŒ€λΆ€λΆ„μ€ 제좜 μ‹œ ꡬ쑰 파일(CIF)을 ν•¨κ»˜ λ‚΄μ‹œλ©΄ λ°”λ‘œ μ±„μ λ©λ‹ˆλ‹€. 행을 λˆ„λ₯΄λ©΄ μ‚¬μœ κ°€ λ‚˜μ˜΅λ‹ˆλ‹€.<br>
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 value</b> means we could not obtain a figure. That is not a fault in the
386
- entry, so it scores nothing rather than zero and stays in the table without a rank.
387
- <b>Waiting does not resolve it.</b> Most cases clear as soon as a structure file (CIF) is included
388
- with the entry. Click the row for the reason.<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,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:"Waiting does not resolve this. Act on the reason below and it will be scored."
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 && !e.is_anchor;
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)}${e.total_max?`<span class="sub" style="font-size:11px"> /${e.total_max}</span>`:""}`;
 
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>