bs82 commited on
Commit
edb73aa
·
verified ·
1 Parent(s): b74e85b

deploy sd35m: 40 pairs

Browse files
Files changed (2) hide show
  1. app/main.py +25 -15
  2. app/static/index.html +5 -4
app/main.py CHANGED
@@ -107,20 +107,26 @@ async def register(req: Request):
107
  return {"token": token, "pairs": pairs}
108
 
109
  def _summarize(votes):
110
- """Per-participant own results (thank-you page): one-click guided-preference counts overall + per style."""
111
- overall = [0, 0]; by_style = {}
 
 
 
112
  for v in votes:
113
  p = PAIRS.get(int(v.get("pair_id", -1)))
114
  ch = v.get("choice")
115
- if not p or p["kind"] != "real" or ch not in ("left", "right"):
116
  continue
117
- gw = int(ch == p["guided_side"])
118
- overall[0] += gw; overall[1] += 1
119
- s = by_style.setdefault(p["style"], [0, 0]); s[0] += gw; s[1] += 1
120
- return {"pref": {"guided": overall[0], "n": overall[1],
121
- "rate": (overall[0] / overall[1]) if overall[1] else None,
122
- "by_style": {k: {"guided": x[0], "n": x[1], "rate": (x[0] / x[1]) if x[1] else None}
123
- for k, x in by_style.items()}}}
 
 
 
124
 
125
  @app.post("/api/submit")
126
  async def submit(req: Request):
@@ -167,13 +173,17 @@ def stats(key: str = ""):
167
  SUM(CASE WHEN guided_chosen IS NULL THEN 1 ELSE 0 END) ties
168
  FROM votes WHERE kind='real' AND question=? AND token IN
169
  (SELECT token FROM participants WHERE completed=1) GROUP BY style""", (q,)).fetchall()
170
- tot = c.execute(f"""SELECT COUNT(*) n, SUM(guided_chosen) g FROM votes
171
- WHERE kind='real' AND question=? AND guided_chosen IS NOT NULL
 
172
  AND token IN (SELECT token FROM participants WHERE completed=1)""", (q,)).fetchone()
 
173
  out["by_question"][q] = {
174
- "overall_n_nontie": tot["n"], "overall_guided_wins": tot["g"],
175
- "overall_guided_winrate": (tot["g"]/tot["n"]) if tot["n"] else None,
176
- "by_style": {r["style"]: {"n": r["n"], "guided": r["g"], "ties": r["ties"]} for r in rows}}
 
 
177
  return out
178
 
179
  @app.get("/api/export")
 
107
  return {"token": token, "pairs": pairs}
108
 
109
  def _summarize(votes):
110
+ """Per-participant own results (thank-you page): three-way win/tie/lose vs our method, overall + per style.
111
+ win = chose ours, tie = 'cannot decide', lose = chose the other; rates are over ALL comparisons (incl. ties)."""
112
+ def tri():
113
+ return [0, 0, 0] # [ours_win, tie, other_win]
114
+ overall = tri(); by_style = {}
115
  for v in votes:
116
  p = PAIRS.get(int(v.get("pair_id", -1)))
117
  ch = v.get("choice")
118
+ if not p or p["kind"] != "real" or ch not in ("left", "right", "cannot"):
119
  continue
120
+ k = 1 if ch == "cannot" else (0 if ch == p["guided_side"] else 2)
121
+ overall[k] += 1
122
+ by_style.setdefault(p["style"], tri())[k] += 1
123
+ def pack(t):
124
+ n = sum(t)
125
+ return {"win": t[0], "tie": t[1], "lose": t[2], "n": n,
126
+ "win_rate": (t[0] / n) if n else None,
127
+ "tie_rate": (t[1] / n) if n else None,
128
+ "lose_rate": (t[2] / n) if n else None}
129
+ return {"pref": {**pack(overall), "by_style": {k: pack(t) for k, t in by_style.items()}}}
130
 
131
  @app.post("/api/submit")
132
  async def submit(req: Request):
 
173
  SUM(CASE WHEN guided_chosen IS NULL THEN 1 ELSE 0 END) ties
174
  FROM votes WHERE kind='real' AND question=? AND token IN
175
  (SELECT token FROM participants WHERE completed=1) GROUP BY style""", (q,)).fetchall()
176
+ tot = c.execute(f"""SELECT COUNT(*) n, SUM(guided_chosen) g,
177
+ SUM(CASE WHEN guided_chosen IS NULL THEN 1 ELSE 0 END) ties
178
+ FROM votes WHERE kind='real' AND question=?
179
  AND token IN (SELECT token FROM participants WHERE completed=1)""", (q,)).fetchone()
180
+ N = tot["n"] or 0; W = tot["g"] or 0; T = tot["ties"] or 0; L = N - W - T # win / tie / lose
181
  out["by_question"][q] = {
182
+ "n": N, "win": W, "tie": T, "lose": L,
183
+ "win_rate": (W/N) if N else None, "tie_rate": (T/N) if N else None, "lose_rate": (L/N) if N else None,
184
+ "decisive_win_rate": (W/(W+L)) if (W+L) else None, # ties dropped (sign-test denominator)
185
+ "by_style": {r["style"]: {"n": r["n"], "win": r["g"] or 0, "tie": r["ties"] or 0,
186
+ "lose": (r["n"] - (r["g"] or 0) - (r["ties"] or 0))} for r in rows}}
187
  return out
188
 
189
  @app.get("/api/export")
app/static/index.html CHANGED
@@ -112,12 +112,13 @@ function renderResults(res){
112
  let rows="";
113
  for(const s of ks){
114
  const ps=p.by_style[s]||{};
115
- rows+=`<tr><td>${STYLE_LBL[s]||s}</td><td>${pct(ps.rate)} <span class="mut">(${ps.guided||0}/${ps.n||0})</span></td></tr>`;
116
  }
117
- const table = ks.length>1 ? `<table><tr class="mut"><th>Style</th><th>Preferred ours</th></tr>${rows}</table>` : "";
118
  $("myresults").innerHTML = `
119
- <p class="center">You preferred <b>our method</b> <b>${pct(p.rate)}</b> of the time
120
- <span class="mut">(${p.guided}/${p.n}; 50% = no preference; the method identity was hidden).</span></p>${table}`;
 
121
  }
122
  fetch("/api/info").then(r=>r.json()).then(d=>{ $("npairs").textContent=d.n_pairs; $("mins").textContent=d.est_minutes; }).catch(()=>{ $("npairs").textContent="a few dozen"; });
123
  $("start").onclick=start;
 
112
  let rows="";
113
  for(const s of ks){
114
  const ps=p.by_style[s]||{};
115
+ rows+=`<tr><td>${STYLE_LBL[s]||s}</td><td>${pct(ps.win_rate)}</td><td>${pct(ps.tie_rate)}</td><td>${pct(ps.lose_rate)}</td></tr>`;
116
  }
117
+ const table = ks.length>1 ? `<table><tr class="mut"><th>Style</th><th>Ours</th><th>No pref.</th><th>Other</th></tr>${rows}</table>` : "";
118
  $("myresults").innerHTML = `
119
+ <p class="center">Over your <b>${p.n}</b> comparisons: you preferred <b>ours ${pct(p.win_rate)}</b>,
120
+ had <b>no preference ${pct(p.tie_rate)}</b>, and preferred <b>the other ${pct(p.lose_rate)}</b>
121
+ <span class="mut">(the method identity was hidden).</span></p>${table}`;
122
  }
123
  fetch("/api/info").then(r=>r.json()).then(d=>{ $("npairs").textContent=d.n_pairs; $("mins").textContent=d.est_minutes; }).catch(()=>{ $("npairs").textContent="a few dozen"; });
124
  $("start").onclick=start;