traits default_value

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

traits default_value

Satrajit Ghosh
hi,

i would like to initialize all my trait attributes to None as the default value

the following works
-----------
class A(HasTraits):
    a = Int(default_value=None)
    b = Float(default_value=None)

assert A().a is None
assert A().b is None
------------

is it possible to achieve the above dynamically in an __init__?
-------------
class MyBaseTraits(HasTraits):
    def __init__(self, **kwargs):
         # set all traits to None ???

class MyTraits(MyBaseTrait):
    a = Int
    b = Float

such that

assert MyTraits().a is None
assert MyTraits().b is None
--------------

Also, is it possible to set a List or Dict trait to a default value of None?
 
cheers,

satra

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Robert Kern
On Mon, Mar 22, 2010 at 2:06 PM, Satrajit Ghosh <[hidden email]> wrote:

> hi,
>
> i would like to initialize all my trait attributes to None as the default
> value
>
> the following works
> -----------
> class A(HasTraits):
>     a = Int(default_value=None)
>     b = Float(default_value=None)
>
> assert A().a is None
> assert A().b is None
> ------------
>
> is it possible to achieve the above dynamically in an __init__?
> -------------
> class MyBaseTraits(HasTraits):
>     def __init__(self, **kwargs):
>          # set all traits to None ???
>
> class MyTraits(MyBaseTrait):
>     a = Int
>     b = Float
>
> such that
>
> assert MyTraits().a is None
> assert MyTraits().b is None
> --------------
>
> Also, is it possible to set a List or Dict trait to a default value of None?

None of those traits accept a None value. Instead, use an Either trait:

In [1]: from enthought.traits.api import *

In [2]: class MyTraits(HasTraits):
   ...:     a = Either(None, Int)
   ...:     b = Either(None, Float)
   ...:
   ...:

In [3]: m = MyTraits()

In [5]: m.a is None
Out[5]: True

In [6]: m.b is None
Out[6]: True

In [7]: m.a = 10

In [8]: m.a
Out[8]: 10

In [9]: m.a = 1.5
---------------------------------------------------------------------------
TraitError                                Traceback (most recent call last)

/Users/rkern/<ipython console> in <module>()

/Users/rkern/svn/et/Traits/enthought/traits/trait_handlers.pyc in
error(self, object, name, value)
    173         """
    174         raise TraitError( object, name, self.full_info(
object, name, value ),
--> 175                           value )
    176
    177     def arg_error ( self, method, arg_num, object, name, value ):

TraitError: The 'a' trait of a MyTraits instance must be an integer or
None, but a value of 1.5 <type 'float'> was specified.

In [10]: m.a = None

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Satrajit Ghosh
dear robert,

thank you. here are a few more details.

None of those traits accept a None value. Instead, use an Either trait:

we don't really want it to accept a None value, we just want the traits to be unset/undefined to begin with, so that we can pass only traits that have been set for further processing. we're using a collection of traits to define an input state of an instance of a process and the user/process can define some subset of this. we want to be able to easily determine which subset was set and pass those along/do computations with them.

In [1]: from enthought.traits.api import *

In [2]: class MyTraits(HasTraits):
  ...:     a = Either(None, Int)
  ...:     b = Either(None, Float)

this is great and will work, but can we do this dynamically during __init__? (it's this dynamic initialization that we have been struggling with). for example a Base Trait class will handle the initialization and recasting during init? the
derived classes will just specify a=Int, b=Float?

we'd like this to happen for every single trait and it seems rather labor intensive to repeat this construct for every single input. we have about a hundred and growing number classes with 10-20 inputs per class that we would like to apply this to. if a dynamic initialization works, it would be great!

cheers,

satra

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Robert Kern
On Mon, Mar 22, 2010 at 2:41 PM, Satrajit Ghosh <[hidden email]> wrote:

> dear robert,
>
> thank you. here are a few more details.
>
>> None of those traits accept a None value. Instead, use an Either trait:
>
> we don't really want it to accept a None value, we just want the traits to
> be unset/undefined to begin with, so that we can pass only traits that have
> been set for further processing. we're using a collection of traits to
> define an input state of an instance of a process and the user/process can
> define some subset of this. we want to be able to easily determine which
> subset was set and pass those along/do computations with them.
>
>> In [1]: from enthought.traits.api import *
>>
>> In [2]: class MyTraits(HasTraits):
>>   ...:     a = Either(None, Int)
>>   ...:     b = Either(None, Float)
>
> this is great and will work, but can we do this dynamically during __init__?
> (it's this dynamic initialization that we have been struggling with). for
> example a Base Trait class will handle the initialization and recasting
> during init? the
> derived classes will just specify a=Int, b=Float?
>
> we'd like this to happen for every single trait and it seems rather labor
> intensive to repeat this construct for every single input. we have about a
> hundred and growing number classes with 10-20 inputs per class that we would
> like to apply this to. if a dynamic initialization works, it would be great!

In [7]: from enthought.traits.api import *

In [8]: class UndefinedBase(HasTraits):
   ...:     def __init__(self, *args, **kwds):
   ...:         super(UndefinedBase, self).__init__(*args, **kwds)
   ...:         undefined_traits = {}
   ...:         for trait in self.trait_names():
   ...:             if trait not in ('trait_added', 'trait_modified'):
   ...:                 undefined_traits[trait] = Undefined
   ...:         self.trait_set(trait_notify=False, **undefined_traits)
   ...:
   ...:

In [27]: class MyTraits(UndefinedBase):
   ....:     a = Int()
   ....:     b = Float()
   ....:
   ....:

In [28]: m = MyTraits()

In [29]: m.a
Out[29]: <undefined>

In [30]: m.b
Out[30]: <undefined>

In [31]: m.a = 10

In [32]: m.a
Out[32]: 10

In [33]: m.a = None
---------------------------------------------------------------------------
TraitError                                Traceback (most recent call last)

/Users/rkern/<ipython console> in <module>()

/Users/rkern/svn/et/Traits/enthought/traits/trait_handlers.pyc in
error(self, object, name, value)
    173         """
    174         raise TraitError( object, name, self.full_info(
object, name, value ),
--> 175                           value )
    176
    177     def arg_error ( self, method, arg_num, object, name, value ):

TraitError: The 'a' trait of a MyTraits instance must be an integer,
but a value of None <type 'NoneType'> was specified.


--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Satrajit Ghosh
thank you.

this is great!

cheers,

satra


In [7]: from enthought.traits.api import *

In [8]: class UndefinedBase(HasTraits):
  ...:     def __init__(self, *args, **kwds):
  ...:         super(UndefinedBase, self).__init__(*args, **kwds)
  ...:         undefined_traits = {}
  ...:         for trait in self.trait_names():
  ...:             if trait not in ('trait_added', 'trait_modified'):
  ...:                 undefined_traits[trait] = Undefined
  ...:         self.trait_set(trait_notify=False, **undefined_traits)

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Christopher Burns
In reply to this post by Robert Kern
On Mon, Mar 22, 2010 at 1:32 PM, Robert Kern <[hidden email]> wrote:
> In [8]: class UndefinedBase(HasTraits):
>   ...:     def __init__(self, *args, **kwds):
>   ...:         super(UndefinedBase, self).__init__(*args, **kwds)
>   ...:         undefined_traits = {}
>   ...:         for trait in self.trait_names():
>   ...:             if trait not in ('trait_added', 'trait_modified'):
>   ...:                 undefined_traits[trait] = Undefined
>   ...:         self.trait_set(trait_notify=False, **undefined_traits)

This worked great Robert, but appears to have exposed a bug.  TraitsUI
list_editor checks for the length of elements of the list and the
_Undefined class does not define __len__.   I checked the traits trunk
and saw that Undefined does not define __len__ there either.

The fix is trivial (unless I'm missing something):

  def __len__(self): return 0

This code should reproduce the error:

import enthought.traits.api as traits

class Foo(traits.HasTraits):
    x = traits.Float(desc = 'x value for Foo')
    center = traits.List(traits.Int, desc = 'center list')

    def __init__(self, **kwargs):
        super(Foo, self).__init__(**kwargs)
        self.x = traits.Undefined
        # XXX Assigning Undefined to traits.List will cause error in
        # TraitsUI list_editor
        self.center = traits.Undefined

if __name__ == '__main__':
    foo = Foo()
    foo.configure_traits()


--
Christopher Burns
Computational Infrastructure for Research Labs
10 Giannini Hall, UC Berkeley
510-643-4053
http://cirl.berkeley.edu/
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Robert Kern
On Fri, Apr 30, 2010 at 12:52 PM, Christopher Burns <[hidden email]> wrote:
> On Mon, Mar 22, 2010 at 1:32 PM, Robert Kern <[hidden email]> wrote:
>> In [8]: class UndefinedBase(HasTraits):
>>   ...:     def __init__(self, *args, **kwds):
>>   ...:         super(UndefinedBase, self).__init__(*args, **kwds)
>>   ...:         undefined_traits = {}
>>   ...:         for trait in self.trait_names():
>>   ...:             if trait not in ('trait_added', 'trait_modified'):
>>   ...:                 undefined_traits[trait] = Undefined
>>   ...:         self.trait_set(trait_notify=False, **undefined_traits)

By the way, there is a typo. It should be "trait_change_notify=False".

> This worked great Robert, but appears to have exposed a bug.  TraitsUI
> list_editor checks for the length of elements of the list and the
> _Undefined class does not define __len__.   I checked the traits trunk
> and saw that Undefined does not define __len__ there either.

I'm not entirely sure I want to try to support Undefineds in all trait
editors. I think the editors should be free to expect fully-defined
traits with valid values when they are initially brought up. That the
list editor works when you fake __len__() == 0 is an accident.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits default_value

Christopher Burns
On Fri, Apr 30, 2010 at 11:03 AM, Robert Kern <[hidden email]> wrote:

> On Fri, Apr 30, 2010 at 12:52 PM, Christopher Burns <[hidden email]> wrote:
>> On Mon, Mar 22, 2010 at 1:32 PM, Robert Kern <[hidden email]> wrote:
>>> In [8]: class UndefinedBase(HasTraits):
>>>   ...:     def __init__(self, *args, **kwds):
>>>   ...:         super(UndefinedBase, self).__init__(*args, **kwds)
>>>   ...:         undefined_traits = {}
>>>   ...:         for trait in self.trait_names():
>>>   ...:             if trait not in ('trait_added', 'trait_modified'):
>>>   ...:                 undefined_traits[trait] = Undefined
>>>   ...:         self.trait_set(trait_notify=False, **undefined_traits)
>
> By the way, there is a typo. It should be "trait_change_notify=False".

Good catch, thanks!

> I'm not entirely sure I want to try to support Undefineds in all trait
> editors. I think the editors should be free to expect fully-defined
> traits with valid values when they are initially brought up. That the
> list editor works when you fake __len__() == 0 is an accident.

Having gone a little further down this road, "fully-defined traits
with valid values" makes sense.  I just discovered that wx does not
know how to set the value of a CheckBox when it's of type 'undefined'
as opposed to 'bool'.  ;)

Thanks Robert.

--
Christopher Burns
Computational Infrastructure for Research Labs
10 Giannini Hall, UC Berkeley
510-643-4053
http://cirl.berkeley.edu/
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev