prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add ability to select random question for interactive demo
  hey @saileshnankani - how about we add a `/random` command to ask a random question from the dev set?
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pyserini/demo/msmarco.py`
  Content:
  ```
  1 #
  2 # Pyserini: Reproducible IR research with sparse and dense representations
  3 #
  4 # Licensed under the Apache License, Version 2.0 (the "License");
  5 # you may not use this file except in compliance with the License.
  6 # You may obtain a copy of the License at
  7 #
  8 # http://www.apache.org/licenses/LICENSE-2.0
  9 #
  10 # Unless required by applicable law or agreed to in writing, software
  11 # distributed under the License is distributed on an "AS IS" BASIS,
  12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 # See the License for the specific language governing permissions and
  14 # limitations under the License.
  15 #
  16 
  17 import cmd
  18 import json
  19 
  20 from pyserini.search import SimpleSearcher
  21 from pyserini.dsearch import SimpleDenseSearcher, TctColBertQueryEncoder, AnceQueryEncoder
  22 from pyserini.hsearch import HybridSearcher
  23 
  24 
  25 class MsMarcoDemo(cmd.Cmd):
  26     ssearcher = SimpleSearcher.from_prebuilt_index('msmarco-passage')
  27     dsearcher = None
  28     hsearcher = None
  29     searcher = ssearcher
  30 
  31     k = 10
  32     prompt = '>>> '
  33 
  34     # https://stackoverflow.com/questions/35213134/command-prefixes-in-python-cli-using-cmd-in-pythons-standard-library
  35     def precmd(self, line):
  36         if line[0] == '/':
  37             line = line[1:]
  38         return line
  39 
  40     def do_help(self, arg):
  41         print(f'/help    : returns this message')
  42         print(f'/k [NUM] : sets k (number of hits to return) to [NUM]')
  43         print(f'/model [MODEL] : sets encoder to use the model [MODEL] (one of tct, ance)')
  44         print(f'/mode [MODE] : sets retriver type to [MODE] (one of sparse, dense, hybrid)')
  45 
  46     def do_k(self, arg):
  47         print(f'setting k = {int(arg)}')
  48         self.k = int(arg)
  49 
  50     def do_mode(self, arg):
  51         if arg == "sparse":
  52             self.searcher = self.ssearcher
  53         elif arg == "dense":
  54             if self.dsearcher is None:
  55                 print(f'Specify model through /model before using dense retrieval.')
  56                 return
  57             self.searcher = self.dsearcher
  58         elif arg == "hybrid":
  59             if self.hsearcher is None:
  60                 print(f'Specify model through /model before using hybrid retrieval.')
  61                 return
  62             self.searcher = self.hsearcher
  63         else:
  64             print(
  65                 f'Mode "{arg}" is invalid. Mode should be one of [sparse, dense, hybrid].')
  66             return
  67         print(f'setting retriver = {arg}')
  68 
  69     def do_model(self, arg):
  70         if arg == "tct":
  71             encoder = TctColBertQueryEncoder("castorini/tct_colbert-msmarco")
  72             index = "msmarco-passage-tct_colbert-hnsw"
  73         elif arg == "ance":
  74             encoder = AnceQueryEncoder("castorini/ance-msmarco-passage")
  75             index = "msmarco-passage-ance-bf"
  76         else:
  77             print(
  78                 f'Model "{arg}" is invalid. Model should be one of [tct, ance].')
  79             return
  80 
  81         self.dsearcher = SimpleDenseSearcher.from_prebuilt_index(
  82             index,
  83             encoder
  84         )
  85         self.hsearcher = HybridSearcher(self.dsearcher, self.ssearcher)
  86         print(f'setting model = {arg}')
  87 
  88     def do_EOF(self, line):
  89         return True
  90 
  91     def default(self, q):
  92         hits = self.searcher.search(q, self.k)
  93 
  94         for i in range(0, len(hits)):
  95             raw_doc = None
  96             if isinstance(self.searcher, SimpleSearcher):
  97                 raw_doc = hits[i].raw
  98             else:
  99                 doc = self.ssearcher.doc(hits[i].docid)
  100                 if doc:
  101                     raw_doc = doc.raw()
  102             jsondoc = json.loads(raw_doc)
  103             print(f'{i + 1:2} {hits[i].score:.5f} {jsondoc["contents"]}')
  104 
  105 
  106 if __name__ == '__main__':
  107     MsMarcoDemo().cmdloop()
  108
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pyserini/demo/msmarco.py b/pyserini/demo/msmarco.py
  --- a/pyserini/demo/msmarco.py
  +++ b/pyserini/demo/msmarco.py
  @@ -16,13 +16,18 @@
   
   import cmd
   import json
  +import os
  +import random
   
   from pyserini.search import SimpleSearcher
   from pyserini.dsearch import SimpleDenseSearcher, TctColBertQueryEncoder, AnceQueryEncoder
   from pyserini.hsearch import HybridSearcher
  +from pyserini import search
   
   
   class MsMarcoDemo(cmd.Cmd):
  +    dev_topics = list(search.get_topics('msmarco-passage-dev-subset').values())
  +
       ssearcher = SimpleSearcher.from_prebuilt_index('msmarco-passage')
       dsearcher = None
       hsearcher = None
  @@ -42,6 +47,7 @@
           print(f'/k [NUM] : sets k (number of hits to return) to [NUM]')
           print(f'/model [MODEL] : sets encoder to use the model [MODEL] (one of tct, ance)')
           print(f'/mode [MODE] : sets retriver type to [MODE] (one of sparse, dense, hybrid)')
  +        print(f'/random : returns results for a random question from dev subset')
   
       def do_k(self, arg):
           print(f'setting k = {int(arg)}')
  @@ -85,6 +91,11 @@
           self.hsearcher = HybridSearcher(self.dsearcher, self.ssearcher)
           print(f'setting model = {arg}')
   
  +    def do_random(self, arg):
  +        q = random.choice(self.dev_topics)['title']
  +        print(f'question: {q}')
  +        self.default(q)
  +
       def do_EOF(self, line):
           return True
  
verification_info: {"golden_diff": "diff --git a/pyserini/demo/msmarco.py b/pyserini/demo/msmarco.py\n--- a/pyserini/demo/msmarco.py\n+++ b/pyserini/demo/msmarco.py\n@@ -16,13 +16,18 @@\n \n import cmd\n import json\n+import os\n+import random\n \n from pyserini.search import SimpleSearcher\n from pyserini.dsearch import SimpleDenseSearcher, TctColBertQueryEncoder, AnceQueryEncoder\n from pyserini.hsearch import HybridSearcher\n+from pyserini import search\n \n \n class MsMarcoDemo(cmd.Cmd):\n+    dev_topics = list(search.get_topics('msmarco-passage-dev-subset').values())\n+\n     ssearcher = SimpleSearcher.from_prebuilt_index('msmarco-passage')\n     dsearcher = None\n     hsearcher = None\n@@ -42,6 +47,7 @@\n         print(f'/k [NUM] : sets k (number of hits to return) to [NUM]')\n         print(f'/model [MODEL] : sets encoder to use the model [MODEL] (one of tct, ance)')\n         print(f'/mode [MODE] : sets retriver type to [MODE] (one of sparse, dense, hybrid)')\n+        print(f'/random : returns results for a random question from dev subset')\n \n     def do_k(self, arg):\n         print(f'setting k = {int(arg)}')\n@@ -85,6 +91,11 @@\n         self.hsearcher = HybridSearcher(self.dsearcher, self.ssearcher)\n         print(f'setting model = {arg}')\n \n+    def do_random(self, arg):\n+        q = random.choice(self.dev_topics)['title']\n+        print(f'question: {q}')\n+        self.default(q)\n+\n     def do_EOF(self, line):\n         return True\n", "issue": "Add ability to select random question for interactive demo\nhey @saileshnankani - how about we add a `/random` command to ask a random question from the dev set?\n", "before_files": [{"content": "#\n# Pyserini: Reproducible IR research with sparse and dense representations\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nimport cmd\nimport json\n\nfrom pyserini.search import SimpleSearcher\nfrom pyserini.dsearch import SimpleDenseSearcher, TctColBertQueryEncoder, AnceQueryEncoder\nfrom pyserini.hsearch import HybridSearcher\n\n\nclass MsMarcoDemo(cmd.Cmd):\n    ssearcher = SimpleSearcher.from_prebuilt_index('msmarco-passage')\n    dsearcher = None\n    hsearcher = None\n    searcher = ssearcher\n\n    k = 10\n    prompt = '>>> '\n\n    # https://stackoverflow.com/questions/35213134/command-prefixes-in-python-cli-using-cmd-in-pythons-standard-library\n    def precmd(self, line):\n        if line[0] == '/':\n            line = line[1:]\n        return line\n\n    def do_help(self, arg):\n        print(f'/help    : returns this message')\n        print(f'/k [NUM] : sets k (number of hits to return) to [NUM]')\n        print(f'/model [MODEL] : sets encoder to use the model [MODEL] (one of tct, ance)')\n        print(f'/mode [MODE] : sets retriver type to [MODE] (one of sparse, dense, hybrid)')\n\n    def do_k(self, arg):\n        print(f'setting k = {int(arg)}')\n        self.k = int(arg)\n\n    def do_mode(self, arg):\n        if arg == \"sparse\":\n            self.searcher = self.ssearcher\n        elif arg == \"dense\":\n            if self.dsearcher is None:\n                print(f'Specify model through /model before using dense retrieval.')\n                return\n            self.searcher = self.dsearcher\n        elif arg == \"hybrid\":\n            if self.hsearcher is None:\n                print(f'Specify model through /model before using hybrid retrieval.')\n                return\n            self.searcher = self.hsearcher\n        else:\n            print(\n                f'Mode \"{arg}\" is invalid. Mode should be one of [sparse, dense, hybrid].')\n            return\n        print(f'setting retriver = {arg}')\n\n    def do_model(self, arg):\n        if arg == \"tct\":\n            encoder = TctColBertQueryEncoder(\"castorini/tct_colbert-msmarco\")\n            index = \"msmarco-passage-tct_colbert-hnsw\"\n        elif arg == \"ance\":\n            encoder = AnceQueryEncoder(\"castorini/ance-msmarco-passage\")\n            index = \"msmarco-passage-ance-bf\"\n        else:\n            print(\n                f'Model \"{arg}\" is invalid. Model should be one of [tct, ance].')\n            return\n\n        self.dsearcher = SimpleDenseSearcher.from_prebuilt_index(\n            index,\n            encoder\n        )\n        self.hsearcher = HybridSearcher(self.dsearcher, self.ssearcher)\n        print(f'setting model = {arg}')\n\n    def do_EOF(self, line):\n        return True\n\n    def default(self, q):\n        hits = self.searcher.search(q, self.k)\n\n        for i in range(0, len(hits)):\n            raw_doc = None\n            if isinstance(self.searcher, SimpleSearcher):\n                raw_doc = hits[i].raw\n            else:\n                doc = self.ssearcher.doc(hits[i].docid)\n                if doc:\n                    raw_doc = doc.raw()\n            jsondoc = json.loads(raw_doc)\n            print(f'{i + 1:2} {hits[i].score:.5f} {jsondoc[\"contents\"]}')\n\n\nif __name__ == '__main__':\n    MsMarcoDemo().cmdloop()\n", "path": "pyserini/demo/msmarco.py"}], "after_files": [{"content": "#\n# Pyserini: Reproducible IR research with sparse and dense representations\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nimport cmd\nimport json\nimport os\nimport random\n\nfrom pyserini.search import SimpleSearcher\nfrom pyserini.dsearch import SimpleDenseSearcher, TctColBertQueryEncoder, AnceQueryEncoder\nfrom pyserini.hsearch import HybridSearcher\nfrom pyserini import search\n\n\nclass MsMarcoDemo(cmd.Cmd):\n    dev_topics = list(search.get_topics('msmarco-passage-dev-subset').values())\n\n    ssearcher = SimpleSearcher.from_prebuilt_index('msmarco-passage')\n    dsearcher = None\n    hsearcher = None\n    searcher = ssearcher\n\n    k = 10\n    prompt = '>>> '\n\n    # https://stackoverflow.com/questions/35213134/command-prefixes-in-python-cli-using-cmd-in-pythons-standard-library\n    def precmd(self, line):\n        if line[0] == '/':\n            line = line[1:]\n        return line\n\n    def do_help(self, arg):\n        print(f'/help    : returns this message')\n        print(f'/k [NUM] : sets k (number of hits to return) to [NUM]')\n        print(f'/model [MODEL] : sets encoder to use the model [MODEL] (one of tct, ance)')\n        print(f'/mode [MODE] : sets retriver type to [MODE] (one of sparse, dense, hybrid)')\n        print(f'/random : returns results for a random question from dev subset')\n\n    def do_k(self, arg):\n        print(f'setting k = {int(arg)}')\n        self.k = int(arg)\n\n    def do_mode(self, arg):\n        if arg == \"sparse\":\n            self.searcher = self.ssearcher\n        elif arg == \"dense\":\n            if self.dsearcher is None:\n                print(f'Specify model through /model before using dense retrieval.')\n                return\n            self.searcher = self.dsearcher\n        elif arg == \"hybrid\":\n            if self.hsearcher is None:\n                print(f'Specify model through /model before using hybrid retrieval.')\n                return\n            self.searcher = self.hsearcher\n        else:\n            print(\n                f'Mode \"{arg}\" is invalid. Mode should be one of [sparse, dense, hybrid].')\n            return\n        print(f'setting retriver = {arg}')\n\n    def do_model(self, arg):\n        if arg == \"tct\":\n            encoder = TctColBertQueryEncoder(\"castorini/tct_colbert-msmarco\")\n            index = \"msmarco-passage-tct_colbert-hnsw\"\n        elif arg == \"ance\":\n            encoder = AnceQueryEncoder(\"castorini/ance-msmarco-passage\")\n            index = \"msmarco-passage-ance-bf\"\n        else:\n            print(\n                f'Model \"{arg}\" is invalid. Model should be one of [tct, ance].')\n            return\n\n        self.dsearcher = SimpleDenseSearcher.from_prebuilt_index(\n            index,\n            encoder\n        )\n        self.hsearcher = HybridSearcher(self.dsearcher, self.ssearcher)\n        print(f'setting model = {arg}')\n\n    def do_random(self, arg):\n        q = random.choice(self.dev_topics)['title']\n        print(f'question: {q}')\n        self.default(q)\n\n    def do_EOF(self, line):\n        return True\n\n    def default(self, q):\n        hits = self.searcher.search(q, self.k)\n\n        for i in range(0, len(hits)):\n            raw_doc = None\n            if isinstance(self.searcher, SimpleSearcher):\n                raw_doc = hits[i].raw\n            else:\n                doc = self.ssearcher.doc(hits[i].docid)\n                if doc:\n                    raw_doc = doc.raw()\n            jsondoc = json.loads(raw_doc)\n            print(f'{i + 1:2} {hits[i].score:.5f} {jsondoc[\"contents\"]}')\n\n\nif __name__ == '__main__':\n    MsMarcoDemo().cmdloop()\n", "path": "pyserini/demo/msmarco.py"}]}