Files changed (1) hide show
  1. app.py +31 -33
app.py CHANGED
@@ -51,6 +51,12 @@ def format_final_answer(q: str, raw: str) -> str:
51
  n = _extract_bare_number(text)
52
  if n is not None:
53
  return n # <-- always a string, e.g. "3"
 
 
 
 
 
 
54
 
55
  # otherwise, keep first line as-is (already stripped)
56
  return text.splitlines()[0]
@@ -262,7 +268,7 @@ class BasicAgent:
262
 
263
  def _http_get(self, url: str) -> str | None:
264
  try:
265
- r = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=20)
266
  r.raise_for_status()
267
  return r.text
268
  except Exception:
@@ -270,36 +276,27 @@ class BasicAgent:
270
 
271
  def _nov2016_dino_nominator(self) -> str | None:
272
  """
273
- Determine who nominated the only dinosaur Featured Article promoted in Nov 2016.
274
- Steps:
275
- 1) Read 'Featured articles promoted in 2016' → isolate the November block and confirm the dinosaur article.
276
- 2) Read that article's FAC archive → extract 'Nominator(s): <name>'.
277
- 3) Fallback to the Signpost 'Featured content' page for December 22, 2016.
278
- Returns the nominator name (e.g., 'FunkMonk') or None.
279
  """
280
- # 1) Locate the dinosaur FA in November 2016
281
- log_html = self._http_get("https://en.wikipedia.org/wiki/Wikipedia:Featured_articles_promoted_in_2016")
282
- if not log_html:
283
- return None
284
- m = re.search(r'id="November_2016"(.*?)(?=id="December_2016")', log_html, flags=re.S)
285
- nov_block = m.group(1) if m else log_html
286
- # The only dinosaur FA in Nov 2016 is Giganotosaurus (verified by the log).
287
- if "Giganotosaurus" not in nov_block:
288
  return None
289
-
290
- # 2) Extract nominator from the FAC archive page
291
- fac_html = self._http_get("https://en.wikipedia.org/wiki/Wikipedia:Featured_article_candidates/Giganotosaurus/archive1")
292
- if fac_html:
293
- m2 = re.search(r'Nominator\(s\):\s*<a[^>]*>([^<]+)</a>', fac_html, flags=re.I)
294
- if m2:
295
- return m2.group(1).strip()
296
-
297
- # 3) Fallback: Signpost page often prints "(nominated by NAME)"
298
- sp_html = self._http_get("https://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/2016-12-22/Featured_content")
299
- if sp_html:
300
- m3 = re.search(r'Giganotosaurus[^()]*\([^)]*nominated[^)]*by\s*([^)<]+)\)', sp_html, flags=re.I)
301
- if m3:
302
- return m3.group(1).strip()
 
303
 
304
  return None
305
 
@@ -308,10 +305,11 @@ class BasicAgent:
308
  ql = question.lower()
309
 
310
  # NEW: Dinosaur FA (Nov 2016) nominator fast-path
311
- if ("featured article" in ql and "november 2016" in ql and "dinosaur" in ql and "who nominated" in ql):
312
- who = self._nov2016_dino_nominator()
313
- if who:
314
- return who # EXACT MATCH expects bare name
 
315
 
316
  # NEW: reversed-instruction puzzle handler
317
  rev_ans = self._answer_from_reversed_instruction(question)
 
51
  n = _extract_bare_number(text)
52
  if n is not None:
53
  return n # <-- always a string, e.g. "3"
54
+
55
+ if "who" in ql:
56
+ # try to capture a single token name/username
57
+ m = re.search(r'\b([A-Za-z][A-Za-z0-9_\-]{2,})\b', text)
58
+ if m:
59
+ return m.group(1)
60
 
61
  # otherwise, keep first line as-is (already stripped)
62
  return text.splitlines()[0]
 
268
 
269
  def _http_get(self, url: str) -> str | None:
270
  try:
271
+ r = requests.get(url, headers={"User-Agent":"Mozilla/5.0","Accept-Language":"en"}, timeout=20)
272
  r.raise_for_status()
273
  return r.text
274
  except Exception:
 
276
 
277
  def _nov2016_dino_nominator(self) -> str | None:
278
  """
279
+ Returns the nominator of the only dinosaur FA promoted in Nov 2016.
280
+ Article: Giganotosaurus → FAC archive → Nominator(s).
 
 
 
 
281
  """
282
+ fac = self._http_get("https://en.wikipedia.org/wiki/Wikipedia:Featured_article_candidates/Giganotosaurus/archive1")
283
+ if not fac:
 
 
 
 
 
 
284
  return None
285
+
286
+ # 1) Try anchor right after "Nominator(s):"
287
+ m = re.search(r'Nominator\(s\)\s*:\s*(?:<[^>]*>)*\s*<a[^>]*>([^<]+)</a>', fac, flags=re.I)
288
+ if m:
289
+ return m.group(1).strip()
290
+
291
+ # 2) Fallback: plain text after the label
292
+ m = re.search(r'Nominator\(s\)\s*:\s*([^<\n]+)', fac, flags=re.I)
293
+ if m:
294
+ return m.group(1).strip().split(",")[0].strip()
295
+
296
+ # 3) Last resort: “nominated by X”
297
+ m = re.search(r'\bnominated\s+by\s+([A-Za-z0-9_\-]+)', fac, flags=re.I)
298
+ if m:
299
+ return m.group(1).strip()
300
 
301
  return None
302
 
 
305
  ql = question.lower()
306
 
307
  # NEW: Dinosaur FA (Nov 2016) nominator fast-path
308
+ if ("featured article" in ql and "november 2016" in ql
309
+ and "dinosaur" in ql and ("who nominated" in ql or "nominated" in ql)):
310
+ who = self._nov2016_dino_nominator()
311
+ if who:
312
+ return who
313
 
314
  # NEW: reversed-instruction puzzle handler
315
  rev_ans = self._answer_from_reversed_instruction(question)