diff --git a/src/commands/cmdhandler.py b/src/commands/cmdhandler.py index fe703d051f..b26a3dc739 100644 --- a/src/commands/cmdhandler.py +++ b/src/commands/cmdhandler.py @@ -316,7 +316,6 @@ def cmdhandler(called_by, raw_string, testing=False, callertype="session", sessi else: # fallback to default error text sysarg = _("Command '%s' is not available.") % raw_string - cmdset.get_all_cmd_keys_and_aliases(caller) suggestions = string_suggestions(raw_string, cmdset.get_all_cmd_keys_and_aliases(caller), cutoff=0.7, maxnum=3) if suggestions: sysarg += _(" Maybe you meant %s?") % utils.list_to_string(suggestions, _('or'), addquote=True) diff --git a/src/commands/command.py b/src/commands/command.py index 280788515d..3e2fd19a14 100644 --- a/src/commands/command.py +++ b/src/commands/command.py @@ -30,7 +30,7 @@ def _init_command(mcs, **kwargs): mcs.aliases = [str(alias).strip().lower() for alias in mcs.aliases.split(',')] except Exception: mcs.aliases = [] - mcs.aliases = list(set(alias for alias in mcs.aliases if alias != mcs.key)) + mcs.aliases = list(set(alias for alias in mcs.aliases if alias and alias != mcs.key)) # optimization - a set is much faster to match against than a list mcs._matchset = set([mcs.key] + mcs.aliases) diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 67c704567a..ea9c879ba8 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -592,7 +592,7 @@ class TagHandler(object): def all(self): "Get all tags in this handler" - return [to_str(p[0]) for p in _GA(self.obj, self._m2m_fieldname).all().values_list("db_key")] + return [to_str(p[0]) for p in _GA(self.obj, self._m2m_fieldname).all().values_list("db_key") if p[0]] def __str__(self): return ",".join(self.all()) diff --git a/src/utils/utils.py b/src/utils/utils.py index 3ef27553de..57cd1ca2fc 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -39,7 +39,6 @@ def is_iter(iterable): except AttributeError: return False - def make_iter(obj): "Makes sure that the object is always iterable." return not hasattr(obj, '__iter__') and [obj] or obj @@ -796,7 +795,7 @@ def string_similarity(string1, string2): This implements a "cosine-similarity" algorithm as described for example in Proceedings of the 22nd International Conference on Computation Linguistics (Coling 2008), pages 593-600, Manchester, August 2008 - The measure vectors used is simply a "bag of words" type histogram (but for letters). + The measure-vectors used is simply a "bag of words" type histogram (but for letters). The function returns a value 0...1 rating how similar the two strings are. The strings can contain multiple words. @@ -804,8 +803,12 @@ def string_similarity(string1, string2): vocabulary = set(list(string1 + string2)) vec1 = [string1.count(v) for v in vocabulary] vec2 = [string2.count(v) for v in vocabulary] - return float(sum(vec1[i]*vec2[i] for i in range(len(vocabulary)))) / \ - (math.sqrt(sum(v1**2 for v1 in vec1)) * math.sqrt(sum(v2**2 for v2 in vec2))) + try: + return float(sum(vec1[i]*vec2[i] for i in range(len(vocabulary)))) / \ + (math.sqrt(sum(v1**2 for v1 in vec1)) * math.sqrt(sum(v2**2 for v2 in vec2))) + except ZeroDivisionError: + # can happen if empty-string cmdnames appear for some reason. This is a no-match. + return 0 def string_suggestions(string, vocabulary, cutoff=0.6, maxnum=3): """