Skip to content

Commit 2a01a78

Browse files
Add examples for different useful traits.
1 parent 9361dcd commit 2a01a78

2 files changed

Lines changed: 211 additions & 4 deletions

File tree

slides/02_traits.md

Lines changed: 210 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,25 @@ moe.edit_traits()
140140
moe.age = 21
141141
```
142142

143+
<!-- #region slideshow={"slide_type": "slide"} -->
144+
## What if you want to override `__init__`?
145+
146+
<!-- #endregion -->
147+
148+
```python
149+
class Child(HasStrictTraits):
150+
age = Int
151+
father = Instance(Parent)
152+
last_name = Delegate('father')
153+
154+
def __init__(self, **traits):
155+
super(HasStrictTraits, self).__init__(**traits)
156+
157+
def _age_changed(self, old, new):
158+
print('Age changed from %s to %s ' % (old, new))
159+
```
160+
161+
143162
<!-- #region slideshow={"slide_type": "slide"} -->
144163
## Predefined trait types
145164

@@ -291,17 +310,171 @@ c = Child(age=21, father=p, first_name='Romano', handedness='right')
291310
p.last_name = 'Ahmed'
292311
```
293312

313+
314+
315+
<!-- #region slideshow={"slide_type": "slide"} -->
316+
## Container traits
317+
318+
- `List`, `Dict` and `Set`
319+
320+
<!-- #endregion -->
321+
322+
<!-- #region slideshow={"slide_type": "slide"} -->
323+
## Trait Lists
324+
325+
326+
<!-- #endregion -->
327+
328+
```python
329+
from traits.api import List
330+
331+
class Bowl(HasStrictTraits):
332+
fruits = List(Str)
333+
334+
@observe("fruits")
335+
def _fruits_list_updated(self, event):
336+
print("fruits list updated", type(event))
337+
print(event.old, event.new)
338+
339+
@observe("fruits.items")
340+
def _fruits_updated(self, event):
341+
print("Fruits items changed", type(event))
342+
print(event.added, event.index, event.removed)
343+
344+
```
345+
346+
```python
347+
b = Bowl()
348+
b.fruits = ['apple']
349+
b.fruits.append('mango')
350+
```
351+
294352
<!-- #region slideshow={"slide_type": "slide"} -->
295353
## Other Trait Events
296354

297-
- Advanced, for other kind of traits
298355
- `List` trait changes: `ListChangeEvent`
299356
- `Dict` trait changes: `DictChangeEvent`
300357
- `Set` trait changes: `SetChangeEvent`
301358

302359
<!-- #endregion -->
303360

361+
<!-- #region slideshow={"slide_type": "slide"} -->
362+
## Some more useful traits
363+
364+
- `File`, `Directory` and `Dict`
365+
- Useful for our application
366+
367+
<!-- #endregion -->
368+
369+
```python
370+
from traits.api import Dict, Directory, File
371+
372+
class Folder(HasStrictTraits):
373+
root = Directory
374+
files = List(File)
375+
sizes = Dict
376+
```
304377

378+
<!-- #region slideshow={"slide_type": "slide"} -->
379+
## Walk through
380+
381+
- Here the dictionary can have any keys or values
382+
- Can use the `key_trait` and `value_trait` to specify them
383+
384+
<!-- #endregion -->
385+
386+
387+
```python
388+
class Folder(HasStrictTraits):
389+
root = Directory
390+
files = List(File)
391+
sizes = Dict(key_trait=Str, value_trait=Dict(Str, Int))
392+
```
393+
394+
```python
395+
f = Folder(root='/tmp')
396+
```
397+
398+
<!-- #region slideshow={"slide_type": "slide"} -->
399+
## Exercise
400+
401+
Modify the above example so when you set `root`, it finds all the files in
402+
that directory and the file sizes and sets the appropriate traits.
403+
404+
Hint: Use `os.listdir` and `os.path.getsize`
405+
406+
<!-- #endregion -->
407+
408+
```python
409+
# Solution
410+
```
411+
412+
413+
414+
<!-- #region slideshow={"slide_type": "slide"} -->
415+
## Property traits
416+
417+
- What if you have a quantity that is computed?
418+
- Use `Property` traits here
419+
- Use the `observe=` kwarg
420+
- Use `@cached_property` to cache output
421+
- Use the `_get_propname` and `_set_propname` (optional)
422+
423+
<!-- #endregion -->
424+
425+
```python
426+
from math import pi
427+
from traits.api import Range, Float, Property, cached_property
428+
429+
class Circle(HasTraits):
430+
radius = Range(0.0, 1000.0)
431+
area = Property(Float, observe='radius')
432+
433+
@cached_property
434+
def _get_area(self):
435+
print("computing area")
436+
return pi*self.radius**2
437+
```
438+
439+
```python
440+
c = Circle(radius=2)
441+
c.area
442+
```
443+
444+
```python
445+
c.area
446+
```
447+
448+
<!-- #region slideshow={"slide_type": "slide"} -->
449+
## `Array` traits
450+
451+
- Can handle numpy arrays of arbitrary shape
452+
- Can specify dtype, shape, and casting options using kwargs
453+
- Warning: cannot "listen" to changes inside the array
454+
- Simple example
455+
456+
<!-- #endregion -->
457+
458+
```python
459+
import numpy as np
460+
from traits.api import Array, Range, observe
461+
462+
class Beats(HasTraits):
463+
f1 = Range(1.0, 200.0, value=100)
464+
f2 = Range(low=1.0, high=200.0, value=104)
465+
signal = Array(dtype=float, shape=(None,))
466+
467+
@observe('f1, f2')
468+
def update(self, event=None):
469+
t = np.linspace(0, 1, 500)
470+
pi = np.pi
471+
self.signal = np.sin(2*pi*self.f1*t) + np.sin(2*pi*self.f2*t)
472+
```
473+
474+
```python
475+
b = Beats()
476+
b.f2 = 103
477+
```
305478
<!-- #region slideshow={"slide_type": "slide"} -->
306479
## Setting default values
307480

@@ -320,7 +493,7 @@ class Thing(HasStrictTraits):
320493
date = Date()
321494
age = Int(12)
322495

323-
def _date_default(self):slideshow={"slide_type": "slide"}
496+
def _date_default(self):
324497
print('default')
325498
return datetime.datetime.today()
326499
```
@@ -334,12 +507,45 @@ t = Thing()
334507
type(c.age)
335508
```
336509

510+
<!-- #region slideshow={"slide_type": "slide"} -->
511+
## `Event` traits
512+
513+
- Holds no value but can be set and be listened to
514+
515+
<!-- #endregion -->
516+
517+
```python
518+
from traits.api import HasTraits
519+
520+
class DataFile(HasStrictTraits):
521+
file = File
522+
data_changed = Event
523+
524+
525+
class DataReader(HasStrictTraits):
526+
file = DataFile
527+
content = Str
528+
529+
@observe("file.data_changed")
530+
def file_data_changed(self, event):
531+
print("File data changed")
532+
533+
```
534+
535+
```python
536+
f = DataFile(file='/tmp/junk.dat')
537+
r = DataReader(file=f)
538+
```
539+
```python
540+
f.data_changed = True
541+
```
337542

338543

339544
<!-- #region slideshow={"slide_type": "slide"} -->
340545
## Exercise time!
341546

342-
- Take the simple example
343-
- Create a simple Traits model
547+
- Take the simple example without traits
548+
- Create a simple Traits model for it
549+
- *Do not do any plotting in the model!*
344550

345551
<!-- #endregion -->

slides/03_traitsui.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ from traits.etsconfig.api import ETSConfig
247247
ETSConfig.toolkit = 'qt'
248248
```
249249
250+
250251
<!-- #region slideshow={"slide_type": "slide"} -->
251252
## Other documentation
252253

0 commit comments

Comments
 (0)