We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Topic Modeling: HDP fails
<!--
This is an issue template. Please fill in the relevant details in the
sections below.
-->

##### Text version
<!-- From menu _Options→Add-ons→Orange3-Text_ or code `orangecontrib.text.version.full_version` -->
0.6.0

##### Orange version
<!-- From menu _Help→About→Version_ or code `Orange.version.full_version` -->
3.21.dev

##### Expected behavior
HDP works.


##### Actual behavior
HDP crashes the widget.


##### Steps to reproduce the behavior
Corpus - Topic Modeling. Select HDP.


##### Additional info (worksheets, data, screenshots, ...)
Upon checking the code, model seems to be fit several times instead of once. The first result is empty, hence the widget fails. Yet to debug further. 



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `orangecontrib/text/topics/topics.py`
Content:
```
1 from gensim import matutils
2 import numpy as np
3 from gensim.corpora import Dictionary
4 
5 from Orange.data import StringVariable, ContinuousVariable, Domain
6 from Orange.data.table import Table
7 from orangecontrib.text.corpus import Corpus
8 from orangecontrib.text.util import chunkable
9 
10 
11 MAX_WORDS = 1000
12 
13 
14 class Topic(Table):
15     """ Dummy wrapper for Table so signals can distinguish Topic from Data.
16     """
17 
18     def __new__(cls, *args, **kwargs):
19         """ Bypass Table.__new__. """
20         return object.__new__(Topic)
21 
22 
23 class GensimWrapper:
24     name = NotImplemented
25     Model = NotImplemented
26     num_topics = NotImplemented
27     has_negative_weights = False    # whether words can negatively contibute to a topic
28 
29     def __init__(self, **kwargs):
30         for k, v in kwargs.items():
31             setattr(self, k, v)
32         self.kwargs = kwargs
33         self.model = None
34         self.topic_names = []
35         self.n_words = 0
36         self.running = False
37 
38     def fit(self, corpus, **kwargs):
39         """ Train the model with the corpus.
40 
41         Args:
42             corpus (Corpus): A corpus to learn topics from.
43         """
44         if not len(corpus.dictionary):
45             return None
46         self.reset_model(corpus)
47         self.running = True
48         self.update(corpus.ngrams_corpus, **kwargs)
49         self.n_words = len(corpus.dictionary)
50         self.topic_names = ['Topic {}'.format(i+1)
51                             for i in range(self.num_topics)]
52         self.running = False
53 
54     def dummy_method(self, *args, **kwargs):
55         pass
56 
57     def reset_model(self, corpus):
58         # prevent model from updating
59         _update = self.Model.update
60         self.Model.update = self.dummy_method
61         self.id2word = Dictionary(corpus.ngrams_iterator(include_postags=True), prune_at=None)
62         self.model = self.Model(corpus=corpus,
63                                 id2word=self.id2word, **self.kwargs)
64         self.Model.update = _update
65 
66     @chunkable
67     def update(self, documents):
68         self.model.update(documents)
69 
70     def transform(self, corpus):
71         """ Create a table with topics representation. """
72         topics = self.model[corpus.ngrams_corpus]
73         matrix = matutils.corpus2dense(topics, num_docs=len(corpus),
74                                        num_terms=self.num_topics).T
75 
76         corpus.extend_attributes(matrix[:, :len(self.topic_names)], self.topic_names)
77         return corpus
78 
79     def fit_transform(self, corpus, **kwargs):
80         self.fit(corpus, **kwargs)
81         return self.transform(corpus)
82 
83     def get_topics_table_by_id(self, topic_id):
84         """ Transform topics from gensim model to table. """
85         words = self._topics_words(MAX_WORDS)
86         weights = self._topics_weights(MAX_WORDS)
87         if topic_id >= len(words):
88             raise ValueError("Too large topic ID.")
89 
90         num_words = len(words[topic_id])
91 
92         data = np.zeros((num_words, 2), dtype=object)
93         data[:, 0] = words[topic_id]
94         data[:, 1] = weights[topic_id]
95 
96         metas = [StringVariable(self.topic_names[topic_id]),
97                  ContinuousVariable("Topic {} weights".format(topic_id + 1))]
98         metas[-1]._out_format = '%.2e'
99 
100         domain = Domain([], metas=metas)
101         t = Topic.from_numpy(domain,
102                              X=np.zeros((num_words, 0)),
103                              metas=data)
104         t.W = data[:, 1]
105         t.name = 'Topic {}'.format(topic_id + 1)
106         return t
107 
108     def get_all_topics_table(self):
109         """ Transform all topics from gensim model to table. """
110         all_words = self._topics_words(self.n_words)
111         all_weights = self._topics_weights(self.n_words)
112         sorted_words = sorted(all_words[0])
113         n_topics = len(all_words)
114 
115         X = []
116         for words, weights in zip(all_words, all_weights):
117             weights = [we for wo, we in sorted(zip(words, weights))]
118             X.append(weights)
119         X = np.array(X).T
120 
121         # take only first n_topics; e.g. when user requested 10, but gensim
122         # returns only 9 — when the rank is lower than num_topics requested
123         attrs = [ContinuousVariable(n)
124                  for n in self.topic_names[:n_topics]]
125 
126         t = Table.from_numpy(Domain(attrs, metas=[StringVariable('Word')]),
127                              X=X, metas=np.array(sorted_words)[:, None])
128         t.name = 'All topics'
129         return t
130 
131     def get_top_words_by_id(self, topic_id, num_of_words=10):
132         topics = self._topics_words(num_of_words=num_of_words)
133         weights = self._topics_weights(num_of_words=num_of_words)
134         if not 0 <= topic_id < self.num_topics:
135             raise ValueError("Invalid {}".format(topic_id))
136         elif topic_id >= len(topics):
137             return [], []
138         return topics[topic_id], weights[topic_id]
139 
140     def _topics_words(self, num_of_words):
141         """ Returns list of list of topic words. """
142         x = self.model.show_topics(-1, num_of_words, formatted=False)
143         # `show_topics` method return a list of `(topic_number, topic)` tuples,
144         # where `topic` is a list of `(word, probability)` tuples.
145         return [[i[0] for i in topic[1]] for topic in x]
146 
147     def _topics_weights(self, num_of_words):
148         """ Returns list of list of topic weights. """
149         topics = self.model.show_topics(-1, num_of_words, formatted=False)
150         # `show_topics` method return a list of `(topic_number, topic)` tuples,
151         # where `topic` is a list of `(word, probability)` tuples.
152         return [[i[1] for i in t[1]] for t in topics]
153
```
--- 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()

```

diff --git a/orangecontrib/text/topics/topics.py b/orangecontrib/text/topics/topics.py
--- a/orangecontrib/text/topics/topics.py
+++ b/orangecontrib/text/topics/topics.py
@@ -139,14 +139,15 @@
 
     def _topics_words(self, num_of_words):
         """ Returns list of list of topic words. """
-        x = self.model.show_topics(-1, num_of_words, formatted=False)
+        x = self.model.show_topics(self.num_topics, num_of_words, formatted=False)
         # `show_topics` method return a list of `(topic_number, topic)` tuples,
         # where `topic` is a list of `(word, probability)` tuples.
         return [[i[0] for i in topic[1]] for topic in x]
 
     def _topics_weights(self, num_of_words):
         """ Returns list of list of topic weights. """
-        topics = self.model.show_topics(-1, num_of_words, formatted=False)
+        topics = self.model.show_topics(self.num_topics, num_of_words,
+                                        formatted=False)
         # `show_topics` method return a list of `(topic_number, topic)` tuples,
         # where `topic` is a list of `(word, probability)` tuples.
         return [[i[1] for i in t[1]] for t in topics]

{"golden_diff": "diff --git a/orangecontrib/text/topics/topics.py b/orangecontrib/text/topics/topics.py\n--- a/orangecontrib/text/topics/topics.py\n+++ b/orangecontrib/text/topics/topics.py\n@@ -139,14 +139,15 @@\n \n     def _topics_words(self, num_of_words):\n         \"\"\" Returns list of list of topic words. \"\"\"\n-        x = self.model.show_topics(-1, num_of_words, formatted=False)\n+        x = self.model.show_topics(self.num_topics, num_of_words, formatted=False)\n         # `show_topics` method return a list of `(topic_number, topic)` tuples,\n         # where `topic` is a list of `(word, probability)` tuples.\n         return [[i[0] for i in topic[1]] for topic in x]\n \n     def _topics_weights(self, num_of_words):\n         \"\"\" Returns list of list of topic weights. \"\"\"\n-        topics = self.model.show_topics(-1, num_of_words, formatted=False)\n+        topics = self.model.show_topics(self.num_topics, num_of_words,\n+                                        formatted=False)\n         # `show_topics` method return a list of `(topic_number, topic)` tuples,\n         # where `topic` is a list of `(word, probability)` tuples.\n         return [[i[1] for i in t[1]] for t in topics]\n", "issue": "Topic Modeling: HDP fails\n<!--\r\nThis is an issue template. Please fill in the relevant details in the\r\nsections below.\r\n-->\r\n\r\n##### Text version\r\n<!-- From menu _Options\u2192Add-ons\u2192Orange3-Text_ or code `orangecontrib.text.version.full_version` -->\r\n0.6.0\r\n\r\n##### Orange version\r\n<!-- From menu _Help\u2192About\u2192Version_ or code `Orange.version.full_version` -->\r\n3.21.dev\r\n\r\n##### Expected behavior\r\nHDP works.\r\n\r\n\r\n##### Actual behavior\r\nHDP crashes the widget.\r\n\r\n\r\n##### Steps to reproduce the behavior\r\nCorpus - Topic Modeling. Select HDP.\r\n\r\n\r\n##### Additional info (worksheets, data, screenshots, ...)\r\nUpon checking the code, model seems to be fit several times instead of once. The first result is empty, hence the widget fails. Yet to debug further. \r\n\r\n\n", "before_files": [{"content": "from gensim import matutils\nimport numpy as np\nfrom gensim.corpora import Dictionary\n\nfrom Orange.data import StringVariable, ContinuousVariable, Domain\nfrom Orange.data.table import Table\nfrom orangecontrib.text.corpus import Corpus\nfrom orangecontrib.text.util import chunkable\n\n\nMAX_WORDS = 1000\n\n\nclass Topic(Table):\n    \"\"\" Dummy wrapper for Table so signals can distinguish Topic from Data.\n    \"\"\"\n\n    def __new__(cls, *args, **kwargs):\n        \"\"\" Bypass Table.__new__. \"\"\"\n        return object.__new__(Topic)\n\n\nclass GensimWrapper:\n    name = NotImplemented\n    Model = NotImplemented\n    num_topics = NotImplemented\n    has_negative_weights = False    # whether words can negatively contibute to a topic\n\n    def __init__(self, **kwargs):\n        for k, v in kwargs.items():\n            setattr(self, k, v)\n        self.kwargs = kwargs\n        self.model = None\n        self.topic_names = []\n        self.n_words = 0\n        self.running = False\n\n    def fit(self, corpus, **kwargs):\n        \"\"\" Train the model with the corpus.\n\n        Args:\n            corpus (Corpus): A corpus to learn topics from.\n        \"\"\"\n        if not len(corpus.dictionary):\n            return None\n        self.reset_model(corpus)\n        self.running = True\n        self.update(corpus.ngrams_corpus, **kwargs)\n        self.n_words = len(corpus.dictionary)\n        self.topic_names = ['Topic {}'.format(i+1)\n                            for i in range(self.num_topics)]\n        self.running = False\n\n    def dummy_method(self, *args, **kwargs):\n        pass\n\n    def reset_model(self, corpus):\n        # prevent model from updating\n        _update = self.Model.update\n        self.Model.update = self.dummy_method\n        self.id2word = Dictionary(corpus.ngrams_iterator(include_postags=True), prune_at=None)\n        self.model = self.Model(corpus=corpus,\n                                id2word=self.id2word, **self.kwargs)\n        self.Model.update = _update\n\n    @chunkable\n    def update(self, documents):\n        self.model.update(documents)\n\n    def transform(self, corpus):\n        \"\"\" Create a table with topics representation. \"\"\"\n        topics = self.model[corpus.ngrams_corpus]\n        matrix = matutils.corpus2dense(topics, num_docs=len(corpus),\n                                       num_terms=self.num_topics).T\n\n        corpus.extend_attributes(matrix[:, :len(self.topic_names)], self.topic_names)\n        return corpus\n\n    def fit_transform(self, corpus, **kwargs):\n        self.fit(corpus, **kwargs)\n        return self.transform(corpus)\n\n    def get_topics_table_by_id(self, topic_id):\n        \"\"\" Transform topics from gensim model to table. \"\"\"\n        words = self._topics_words(MAX_WORDS)\n        weights = self._topics_weights(MAX_WORDS)\n        if topic_id >= len(words):\n            raise ValueError(\"Too large topic ID.\")\n\n        num_words = len(words[topic_id])\n\n        data = np.zeros((num_words, 2), dtype=object)\n        data[:, 0] = words[topic_id]\n        data[:, 1] = weights[topic_id]\n\n        metas = [StringVariable(self.topic_names[topic_id]),\n                 ContinuousVariable(\"Topic {} weights\".format(topic_id + 1))]\n        metas[-1]._out_format = '%.2e'\n\n        domain = Domain([], metas=metas)\n        t = Topic.from_numpy(domain,\n                             X=np.zeros((num_words, 0)),\n                             metas=data)\n        t.W = data[:, 1]\n        t.name = 'Topic {}'.format(topic_id + 1)\n        return t\n\n    def get_all_topics_table(self):\n        \"\"\" Transform all topics from gensim model to table. \"\"\"\n        all_words = self._topics_words(self.n_words)\n        all_weights = self._topics_weights(self.n_words)\n        sorted_words = sorted(all_words[0])\n        n_topics = len(all_words)\n\n        X = []\n        for words, weights in zip(all_words, all_weights):\n            weights = [we for wo, we in sorted(zip(words, weights))]\n            X.append(weights)\n        X = np.array(X).T\n\n        # take only first n_topics; e.g. when user requested 10, but gensim\n        # returns only 9 \u2014 when the rank is lower than num_topics requested\n        attrs = [ContinuousVariable(n)\n                 for n in self.topic_names[:n_topics]]\n\n        t = Table.from_numpy(Domain(attrs, metas=[StringVariable('Word')]),\n                             X=X, metas=np.array(sorted_words)[:, None])\n        t.name = 'All topics'\n        return t\n\n    def get_top_words_by_id(self, topic_id, num_of_words=10):\n        topics = self._topics_words(num_of_words=num_of_words)\n        weights = self._topics_weights(num_of_words=num_of_words)\n        if not 0 <= topic_id < self.num_topics:\n            raise ValueError(\"Invalid {}\".format(topic_id))\n        elif topic_id >= len(topics):\n            return [], []\n        return topics[topic_id], weights[topic_id]\n\n    def _topics_words(self, num_of_words):\n        \"\"\" Returns list of list of topic words. \"\"\"\n        x = self.model.show_topics(-1, num_of_words, formatted=False)\n        # `show_topics` method return a list of `(topic_number, topic)` tuples,\n        # where `topic` is a list of `(word, probability)` tuples.\n        return [[i[0] for i in topic[1]] for topic in x]\n\n    def _topics_weights(self, num_of_words):\n        \"\"\" Returns list of list of topic weights. \"\"\"\n        topics = self.model.show_topics(-1, num_of_words, formatted=False)\n        # `show_topics` method return a list of `(topic_number, topic)` tuples,\n        # where `topic` is a list of `(word, probability)` tuples.\n        return [[i[1] for i in t[1]] for t in topics]\n", "path": "orangecontrib/text/topics/topics.py"}], "after_files": [{"content": "from gensim import matutils\nimport numpy as np\nfrom gensim.corpora import Dictionary\n\nfrom Orange.data import StringVariable, ContinuousVariable, Domain\nfrom Orange.data.table import Table\nfrom orangecontrib.text.corpus import Corpus\nfrom orangecontrib.text.util import chunkable\n\n\nMAX_WORDS = 1000\n\n\nclass Topic(Table):\n    \"\"\" Dummy wrapper for Table so signals can distinguish Topic from Data.\n    \"\"\"\n\n    def __new__(cls, *args, **kwargs):\n        \"\"\" Bypass Table.__new__. \"\"\"\n        return object.__new__(Topic)\n\n\nclass GensimWrapper:\n    name = NotImplemented\n    Model = NotImplemented\n    num_topics = NotImplemented\n    has_negative_weights = False    # whether words can negatively contibute to a topic\n\n    def __init__(self, **kwargs):\n        for k, v in kwargs.items():\n            setattr(self, k, v)\n        self.kwargs = kwargs\n        self.model = None\n        self.topic_names = []\n        self.n_words = 0\n        self.running = False\n\n    def fit(self, corpus, **kwargs):\n        \"\"\" Train the model with the corpus.\n\n        Args:\n            corpus (Corpus): A corpus to learn topics from.\n        \"\"\"\n        if not len(corpus.dictionary):\n            return None\n        self.reset_model(corpus)\n        self.running = True\n        self.update(corpus.ngrams_corpus, **kwargs)\n        self.n_words = len(corpus.dictionary)\n        self.topic_names = ['Topic {}'.format(i+1)\n                            for i in range(self.num_topics)]\n        self.running = False\n\n    def dummy_method(self, *args, **kwargs):\n        pass\n\n    def reset_model(self, corpus):\n        # prevent model from updating\n        _update = self.Model.update\n        self.Model.update = self.dummy_method\n        self.id2word = Dictionary(corpus.ngrams_iterator(include_postags=True), prune_at=None)\n        self.model = self.Model(corpus=corpus,\n                                id2word=self.id2word, **self.kwargs)\n        self.Model.update = _update\n\n    @chunkable\n    def update(self, documents):\n        self.model.update(documents)\n\n    def transform(self, corpus):\n        \"\"\" Create a table with topics representation. \"\"\"\n        topics = self.model[corpus.ngrams_corpus]\n        matrix = matutils.corpus2dense(topics, num_docs=len(corpus),\n                                       num_terms=self.num_topics).T\n\n        corpus.extend_attributes(matrix[:, :len(self.topic_names)], self.topic_names)\n        return corpus\n\n    def fit_transform(self, corpus, **kwargs):\n        self.fit(corpus, **kwargs)\n        return self.transform(corpus)\n\n    def get_topics_table_by_id(self, topic_id):\n        \"\"\" Transform topics from gensim model to table. \"\"\"\n        words = self._topics_words(MAX_WORDS)\n        weights = self._topics_weights(MAX_WORDS)\n        if topic_id >= len(words):\n            raise ValueError(\"Too large topic ID.\")\n\n        num_words = len(words[topic_id])\n\n        data = np.zeros((num_words, 2), dtype=object)\n        data[:, 0] = words[topic_id]\n        data[:, 1] = weights[topic_id]\n\n        metas = [StringVariable(self.topic_names[topic_id]),\n                 ContinuousVariable(\"Topic {} weights\".format(topic_id + 1))]\n        metas[-1]._out_format = '%.2e'\n\n        domain = Domain([], metas=metas)\n        t = Topic.from_numpy(domain,\n                             X=np.zeros((num_words, 0)),\n                             metas=data)\n        t.W = data[:, 1]\n        t.name = 'Topic {}'.format(topic_id + 1)\n        return t\n\n    def get_all_topics_table(self):\n        \"\"\" Transform all topics from gensim model to table. \"\"\"\n        all_words = self._topics_words(self.n_words)\n        all_weights = self._topics_weights(self.n_words)\n        sorted_words = sorted(all_words[0])\n        n_topics = len(all_words)\n\n        X = []\n        for words, weights in zip(all_words, all_weights):\n            weights = [we for wo, we in sorted(zip(words, weights))]\n            X.append(weights)\n        X = np.array(X).T\n\n        # take only first n_topics; e.g. when user requested 10, but gensim\n        # returns only 9 \u2014 when the rank is lower than num_topics requested\n        attrs = [ContinuousVariable(n)\n                 for n in self.topic_names[:n_topics]]\n\n        t = Table.from_numpy(Domain(attrs, metas=[StringVariable('Word')]),\n                             X=X, metas=np.array(sorted_words)[:, None])\n        t.name = 'All topics'\n        return t\n\n    def get_top_words_by_id(self, topic_id, num_of_words=10):\n        topics = self._topics_words(num_of_words=num_of_words)\n        weights = self._topics_weights(num_of_words=num_of_words)\n        if not 0 <= topic_id < self.num_topics:\n            raise ValueError(\"Invalid {}\".format(topic_id))\n        elif topic_id >= len(topics):\n            return [], []\n        return topics[topic_id], weights[topic_id]\n\n    def _topics_words(self, num_of_words):\n        \"\"\" Returns list of list of topic words. \"\"\"\n        x = self.model.show_topics(self.num_topics, num_of_words, formatted=False)\n        # `show_topics` method return a list of `(topic_number, topic)` tuples,\n        # where `topic` is a list of `(word, probability)` tuples.\n        return [[i[0] for i in topic[1]] for topic in x]\n\n    def _topics_weights(self, num_of_words):\n        \"\"\" Returns list of list of topic weights. \"\"\"\n        topics = self.model.show_topics(self.num_topics, num_of_words,\n                                        formatted=False)\n        # `show_topics` method return a list of `(topic_number, topic)` tuples,\n        # where `topic` is a list of `(word, probability)` tuples.\n        return [[i[1] for i in t[1]] for t in topics]\n", "path": "orangecontrib/text/topics/topics.py"}]}