dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #10190
Re: New Function implementation
2008/10/19 Anders Logg <logg@xxxxxxxxx>:
> On Sun, Oct 19, 2008 at 09:04:17PM +0200, Johan Hake wrote:
>> On Sunday 19 October 2008 00:24:36 Anders Logg wrote:
>> > On Sat, Oct 18, 2008 at 11:55:32PM +0200, Johan Hake wrote:
>> > > On Saturday 18 October 2008 23:23:24 Anders Logg wrote:
>> > > > On Sat, Oct 18, 2008 at 10:16:32PM +0200, Johan Hake wrote:
>> > > > > On Saturday 18 October 2008 21:24:53 Anders Logg wrote:
>> > > > > > On Thu, Oct 16, 2008 at 03:38:01PM +0200, Martin Sandve Alnæs wrote:
>> > > > > > > "in" is a reserved keyword in python. Suggestions:
>> > > > > > > "f.in_space(V)" or "f.in_function_space(V)" or "f.member(V)"
>> > > > > >
>> > > > > > How about keeping u.in(V) in C++ and then map it to something
>> > > > > > suitable in Python so that one may write
>> > > > > >
>> > > > > > if u in V:
>> > > > > > ...
>> > > > > >
>> > > > > > in Python. Does anyone know how to do that?
>> > > > >
>> > > > > There is a problem in the logic here. In c++ you ask the function if
>> > > > > it is in a certain FunctionSpace, but the python code "u in V" would
>> > > > > check if u is in V by calling V.__contains__(u). To make it more
>> > > > > consistent we could implement the 'in' function in FunctionSpace, and
>> > > > > then just rename 'in' to __contains__.
>> > > > >
>> > > > > You could also keep it the way it is and then rename Function.in to
>> > > > > let say Function._in and then extend FunctionSpace with
>> > > > >
>> > > > > def __contains__(self,u).
>> > > > > assert(u,Function)
>> > > > > return u._in(self)
>> > > > >
>> > > > > But then we would have different logics in c++ and python.
>> > > > >
>> > > > > Johan
>> > > >
>> > > > I think that would be ok, considering it is Python that maps "in" to
>> > > > "contains". The logic and notation from a user perspective would be
>> > > > the same in C++ and Python:
>> > > >
>> > > > if (u.in(V))
>> > > > {
>> > > >
>> > > > }
>> > > >
>> > > > if u in V:
>> > >
>> > > I see your point and I agree.
>> > >
>> > > My logical error was attached to who implemented what. But to get the
>> > > nice and from a user perspective logical syntax you present above, we
>> > > need to implement it differently in c++ and python.
>> >
>> > ok, good. Can you implement it?
>>
>> Yes, but I would like to have Martins feedback on how 'pythonic' the
>> implementation is.
>>
>> In most regards will the python version, "u in V" answer the question "is u an
>> item in V", where V is interpreted as a sequence or container. The function,
>> u is strictly speeking not an item in V. You can for example not access u
>> from V.
>>
>> It's just a gut feeling I have that we might stretch the python interface a
>> bit here. This is maybee not a bad idea when you have the somewhat
>> minimalistic function name 'in' from c++ in mind, but if you have a pure
>> python background it could be a bit confusing.
>
> ok.
>
>> I think I would go for the _slightly_ more verbal u.in_space(V)
>> implementation. You should not avoid two word function name for all cost ;)
>
> I don't mind longer function names now that we don't use camelCaps
> anymore... :-)
>
> I'll wait for Martin's opinion.
>
> --
> Anders
As Johan said, "a in b" or equivalently b.__contains__(a) is usually
taken to mean "a is an item in the container b". If type(b) is a
container type, it would be essential for __contains__ to have this
meaning, as it is a part of the "mapping protocol".
However, since FunctionSpace is not a container type, overloading
FunctionSpace.__contains__(self, f) to mean "f in self" shouldn't pose
any problems that I see. There may exist python code in the world at
large that assumes an implementation of __contains__ means a container
type, but we don't need to interact with that code anyway.
So I think we can safely e.g. rename "Function::in" to
"Function::in_space" in the swig interface, and then extend
FunctionSpace with an implementation of __contains__ like this:
def __contains__(self, f):
return f.in_space(self)
--
Martin
Follow ups
References