Suggesting methods with similar names

B

bearophileHUGS

I have a class Surface with many methods. Working in the interactive
window I receive an error like this when I write the wrong method name:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Surface' object has no attribute 'addGlas'

Is it possibile to make the object give a better answer: a short list
of few method names similar to the one I've misspelled?

I've found some modules with phonetic algorithms like soundex,
metaphone, etc, for example here:
http://sourceforge.net/projects/advas/

I can produce the list of method names with this:
toRemove = """__delattr__ __dict__ __getattribute__ __module__ __new__
__reduce__ __copy__ __reduce_ex__ __setattr__ __slot__
__weakref__ __str__ __class__ __doc__""".split()
methods = sorted( set(dir(Surface)).difference(toRemove) )

The problem is calling the phonetic algorithm to show a ranked list of
the 2-4 method names most similar to the wrong one called. I don't know
if this problem requires a change in the python shell, or in the
metaclass of that Surface class, etc.
And in the end maybe this functionality (inspired by a similar
Mathematica one) is already inside IPython :-]

Bye,
Bearophile
 
B

Benjamin Niemann

I have a class Surface with many methods. Working in the interactive
window I receive an error like this when I write the wrong method name:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Surface' object has no attribute 'addGlas'

Is it possibile to make the object give a better answer: a short list
of few method names similar to the one I've misspelled?

I've found some modules with phonetic algorithms like soundex,
metaphone, etc, for example here:
http://sourceforge.net/projects/advas/

I can produce the list of method names with this:
toRemove = """__delattr__ __dict__ __getattribute__ __module__ __new__
__reduce__ __copy__ __reduce_ex__ __setattr__ __slot__
__weakref__ __str__ __class__ __doc__""".split()
methods = sorted( set(dir(Surface)).difference(toRemove) )

The problem is calling the phonetic algorithm to show a ranked list of
the 2-4 method names most similar to the wrong one called. I don't know
if this problem requires a change in the python shell, or in the
metaclass of that Surface class, etc.
And in the end maybe this functionality (inspired by a similar
Mathematica one) is already inside IPython :-]
You could achieve this by overriding __getattribute__ (untested):

def __getattribute__(self, name):
try:
object.__getattribute__(self, name) # or whatever is your superclass
# or use super(), but I would have to lookup the syntax and
# breakfast is waiting ;)
except AttributeError:
# find similar attributes
suggestions = ....
raise AttributeError("'Surface' object has no attribute '%s'. Did you
mean %s?" % (name, suggestions))

I leave it to the experts to wrap this into a generic metaclass, decorator
etc. ;)
 
T

Terry Reedy

You could achieve this by overriding __getattribute__ (untested):

I believe OP would do better to use __getattr__, which is only called when
the attribute is not found by the normal lookup, which is the only time he
needs/wants customized control.

TJR
 
B

bearophileHUGS

Thank you, __getattr__ does what I need :)
A smart help can be designed easely...

Bear hugs,
Bearophile
 
R

Raymond Hettinger

[Bearophile]
Working in the interactive window I receive an error like
this when I write the wrong method name:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Surface' object has no attribute 'addGlas'

Is it possibile to make the object give a better answer: a short list
of few method names similar to the one I've misspelled?
[Bearophile]
Thank you, __getattr__ does what I need :)
A smart help can be designed easely...

The idea is a winner. When you're done, consider posting the result as an ASPN
cookbook recipe.


Raymond Hettinger
 
B

bearophileHUGS

Raymond Hettinger>When you're done, consider posting the result as an
ASPN cookbook recipe.<

I still cannot write in the cookbook... I think I have problems with
the registration. So you can put it there...
I've found that difflib is good enough for the string matching. This
idea isn't fully mine, it's modified from the Mathematica textual
interface. Here is the code with long lines:

| def __getattr__(self, name):
| "If a wrong method is called, suggest methods with similar
names."
| def match(str1, str2):
| "Return approximate string comparator measure (between 0.0
and 1.0) using difflib."
| if str1 == str2:
| return 1.0
| m1 = SequenceMatcher(None, str1, str2)
| m2 = SequenceMatcher(None, str2, str1)
| return (m1.ratio()+m2.ratio()) / 2.0 # average
|
| toRemove = """__delattr__ __dict__ __getattribute__ __module__
__new__ __reduce__ __copy__
| __reduce_ex__ __setattr__ __slot__ __weakref__ __str__
__class__ __doc__""".split()
| methods = set(dir(self.__class__)).difference(toRemove)
| name = name.lower()
| matchList = [ (match(name, m.lower()),m) for m in methods ]
| suggestions = sorted(matchList, reverse=True)[:5] # A heap isn't
necessary here
| suggestions = ", ".join( pair[1] for pair in suggestions )
| raise AttributeError, ("method '%s' not found. \nMost similar
named ones: %s" % (name, suggestions))

Note: the general idea of a smart help can be improved a *lot*, this is
the basic version :-]

Bear hugs,
Bearophile
 
D

Diez B. Roggisch

I have a class Surface with many methods. Working in the interactive
window I receive an error like this when I write the wrong method name:

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Surface' object has no attribute 'addGlas'

Is it possibile to make the object give a better answer: a short list
of few method names similar to the one I've misspelled?

Have you heard of rlcompleter2? It gives you tab-completion on the repl.

While your idea looks nice at first glance, what I don't like about it that
it will make an object return always _something_ - and thus you don't catch
misspellings in non-interactive, or at least not where they actually happen
but when you try to work with the results.
 
B

bearophileHUGS

Diez B. Roggisch>it will make an object return always _something_ - and
thus you don't catch misspellings in non-interactive<

Uhm, I'm sorry, I don't understand you.
If you look at the code I've just posted, you can see that it still
raises AttributeError, the difference is just the error message...

Bearophile
 
B

Bengt Richter

[Bearophile]
Working in the interactive window I receive an error like
this when I write the wrong method name:
table.addGlas()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Surface' object has no attribute 'addGlas'

Is it possibile to make the object give a better answer: a short list
of few method names similar to the one I've misspelled?
[Bearophile]
Thank you, __getattr__ does what I need :)
A smart help can be designed easely...

The idea is a winner. When you're done, consider posting the result as an ASPN
cookbook recipe.
Interactively, I often use dir(whatever) to find methods, but I sure wish dir had
some keyword arguments to limit the returned info various ways, e.g., methods
of the immediate class, not the whole mro, and optionally without the __xxx__ methods.
Ditto with help().


BTW, when are we going to be able to write

@classdeco
class Foo(object):
...

so we can implement smart help as a decorator?

I.e., the above decorator syntax would be a non-intrusive way of spelling

class Foo(object):
__metaclass__ = classdeco
...

(haven't thought about cascaded decorators in this context ;-)

Regards,
Bengt Richter
 
T

Terry Reedy

Bengt Richter said:
BTW, when are we going to be able to write

@classdeco
class Foo(object):

That possibility is currently being discussed for 2.5 on the pydev list.
There are mixed opinions, none yet from Guido that I noticed.

Terry J. Reedy
 
B

bearophileHUGS

Suggesting method names based on a wrong method name can be useful, but
I think the "smart help" can be improved: it can also be useful to have
a suggestion for method names on the basis on a short description (or
keywords) about what I want to do to/with the object. Maybe some people
here can give me some suggestions on how to do this.

I think I can add a
Keywords: xxxx, xxx, xxxx.
final part to each docstring of the methods, so a kind of little search
engine can search for the few most fitting methods based on the user
text search query, and on the methods keywords+doc texts.

User query example:
"How to rotate the object"

Result (a short ranked list of method names that can perform that
operation):
rotate, flip, pivot, mirror

(Note: the query is inserted calling a "help" method, or something
similar, etc. It doesn't require any magic.)
Do you know any little search engine that can be used for this purpose?

Thank you,
Bearophile
 
B

bearophileHUGS

Is that last idea so stupid? Still, I'd like to know if you know some
little Python search engines for such purpose.

Thank you,
Bearophile
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top