##// END OF EJS Templates
set readout=True as default on SliderWidgets
MinRK -
Show More
@@ -1,402 +1,408 b''
1 1 """Test interact and interactive."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2014 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 from __future__ import print_function
15 15
16 16 from collections import OrderedDict
17 17
18 18 import nose.tools as nt
19 19 import IPython.testing.tools as tt
20 20
21 21 # from IPython.core.getipython import get_ipython
22 22 from IPython.html import widgets
23 23 from IPython.html.widgets import interact, interactive, Widget, interaction
24 24 from IPython.utils.py3compat import annotate
25 25 # from IPython.utils.capture import capture_output
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Utility stuff
29 29 #-----------------------------------------------------------------------------
30 30
31 31 class DummyComm(object):
32 32 comm_id = 'a-b-c-d'
33 33 def send(self, *args, **kwargs):
34 34 pass
35 35
36 36 def close(self, *args, **kwargs):
37 37 pass
38 38
39 39 _widget_attrs = {}
40 40 displayed = []
41 41
42 42 def setup():
43 43 _widget_attrs['comm'] = Widget.comm
44 44 Widget.comm = DummyComm()
45 45 _widget_attrs['_ipython_display_'] = Widget._ipython_display_
46 46 def raise_not_implemented(*args, **kwargs):
47 47 raise NotImplementedError()
48 48 Widget._ipython_display_ = raise_not_implemented
49 49
50 50 def teardown():
51 51 for attr, value in _widget_attrs.items():
52 52 setattr(Widget, attr, value)
53 53
54 54 def f(**kwargs):
55 55 pass
56 56
57 57 def clear_display():
58 58 global displayed
59 59 displayed = []
60 60
61 61 def record_display(*args):
62 62 displayed.extend(args)
63 63
64 64 #-----------------------------------------------------------------------------
65 65 # Actual tests
66 66 #-----------------------------------------------------------------------------
67 67
68 68 def check_widget(w, **d):
69 69 """Check a single widget against a dict"""
70 70 for attr, expected in d.items():
71 71 if attr == 'cls':
72 72 nt.assert_is(w.__class__, expected)
73 73 else:
74 74 value = getattr(w, attr)
75 75 nt.assert_equal(value, expected,
76 76 "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected)
77 77 )
78 78
79 79 def check_widgets(container, **to_check):
80 80 """Check that widgets are created as expected"""
81 81 # build a widget dictionary, so it matches
82 82 widgets = {}
83 83 for w in container.children:
84 84 widgets[w.description] = w
85 85
86 86 for key, d in to_check.items():
87 87 nt.assert_in(key, widgets)
88 88 check_widget(widgets[key], **d)
89 89
90 90
91 91 def test_single_value_string():
92 92 a = u'hello'
93 93 c = interactive(f, a=a)
94 94 w = c.children[0]
95 95 check_widget(w,
96 96 cls=widgets.TextWidget,
97 97 description='a',
98 98 value=a,
99 99 )
100 100
101 101 def test_single_value_bool():
102 102 for a in (True, False):
103 103 c = interactive(f, a=a)
104 104 w = c.children[0]
105 105 check_widget(w,
106 106 cls=widgets.CheckboxWidget,
107 107 description='a',
108 108 value=a,
109 109 )
110 110
111 111 def test_single_value_dict():
112 112 for d in [
113 113 dict(a=5),
114 114 dict(a=5, b='b', c=dict),
115 115 ]:
116 116 c = interactive(f, d=d)
117 117 w = c.children[0]
118 118 check_widget(w,
119 119 cls=widgets.DropdownWidget,
120 120 description='d',
121 121 values=d,
122 122 value=next(iter(d.values())),
123 123 )
124 124
125 125 def test_single_value_float():
126 126 for a in (2.25, 1.0, -3.5):
127 127 c = interactive(f, a=a)
128 128 w = c.children[0]
129 129 check_widget(w,
130 130 cls=widgets.FloatSliderWidget,
131 131 description='a',
132 132 value=a,
133 133 min= -a if a > 0 else 3*a,
134 134 max= 3*a if a > 0 else -a,
135 135 step=0.1,
136 readout=True,
136 137 )
137 138
138 139 def test_single_value_int():
139 140 for a in (1, 5, -3):
140 141 c = interactive(f, a=a)
141 142 nt.assert_equal(len(c.children), 1)
142 143 w = c.children[0]
143 144 check_widget(w,
144 145 cls=widgets.IntSliderWidget,
145 146 description='a',
146 147 value=a,
147 148 min= -a if a > 0 else 3*a,
148 149 max= 3*a if a > 0 else -a,
149 150 step=1,
151 readout=True,
150 152 )
151 153
152 154 def test_list_tuple_2_int():
153 155 with nt.assert_raises(ValueError):
154 156 c = interactive(f, tup=(1,1))
155 157 with nt.assert_raises(ValueError):
156 158 c = interactive(f, tup=(1,-1))
157 159 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
158 160 c = interactive(f, tup=(min, max), lis=[min, max])
159 161 nt.assert_equal(len(c.children), 2)
160 162 d = dict(
161 163 cls=widgets.IntSliderWidget,
162 164 min=min,
163 165 max=max,
164 166 step=1,
167 readout=True,
165 168 )
166 169 check_widgets(c, tup=d, lis=d)
167 170
168 171 def test_list_tuple_3_int():
169 172 with nt.assert_raises(ValueError):
170 173 c = interactive(f, tup=(1,2,0))
171 174 with nt.assert_raises(ValueError):
172 175 c = interactive(f, tup=(1,2,-1))
173 176 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
174 177 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
175 178 nt.assert_equal(len(c.children), 2)
176 179 d = dict(
177 180 cls=widgets.IntSliderWidget,
178 181 min=min,
179 182 max=max,
180 183 step=step,
184 readout=True,
181 185 )
182 186 check_widgets(c, tup=d, lis=d)
183 187
184 188 def test_list_tuple_2_float():
185 189 with nt.assert_raises(ValueError):
186 190 c = interactive(f, tup=(1.0,1.0))
187 191 with nt.assert_raises(ValueError):
188 192 c = interactive(f, tup=(0.5,-0.5))
189 193 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
190 194 c = interactive(f, tup=(min, max), lis=[min, max])
191 195 nt.assert_equal(len(c.children), 2)
192 196 d = dict(
193 197 cls=widgets.FloatSliderWidget,
194 198 min=min,
195 199 max=max,
196 200 step=.1,
201 readout=True,
197 202 )
198 203 check_widgets(c, tup=d, lis=d)
199 204
200 205 def test_list_tuple_3_float():
201 206 with nt.assert_raises(ValueError):
202 207 c = interactive(f, tup=(1,2,0.0))
203 208 with nt.assert_raises(ValueError):
204 209 c = interactive(f, tup=(-1,-2,1.))
205 210 with nt.assert_raises(ValueError):
206 211 c = interactive(f, tup=(1,2.,-1.))
207 212 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
208 213 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
209 214 nt.assert_equal(len(c.children), 2)
210 215 d = dict(
211 216 cls=widgets.FloatSliderWidget,
212 217 min=min,
213 218 max=max,
214 219 step=step,
220 readout=True,
215 221 )
216 222 check_widgets(c, tup=d, lis=d)
217 223
218 224 def test_list_tuple_str():
219 225 values = ['hello', 'there', 'guy']
220 226 first = values[0]
221 227 dvalues = OrderedDict((v,v) for v in values)
222 228 c = interactive(f, tup=tuple(values), lis=list(values))
223 229 nt.assert_equal(len(c.children), 2)
224 230 d = dict(
225 231 cls=widgets.DropdownWidget,
226 232 value=first,
227 233 values=dvalues
228 234 )
229 235 check_widgets(c, tup=d, lis=d)
230 236
231 237 def test_list_tuple_invalid():
232 238 for bad in [
233 239 (),
234 240 (5, 'hi'),
235 241 ('hi', 5),
236 242 ({},),
237 243 (None,),
238 244 ]:
239 245 with nt.assert_raises(ValueError):
240 246 print(bad) # because there is no custom message in assert_raises
241 247 c = interactive(f, tup=bad)
242 248
243 249 def test_defaults():
244 250 @annotate(n=10)
245 251 def f(n, f=4.5):
246 252 pass
247 253
248 254 c = interactive(f)
249 255 check_widgets(c,
250 256 n=dict(
251 257 cls=widgets.IntSliderWidget,
252 258 value=10,
253 259 ),
254 260 f=dict(
255 261 cls=widgets.FloatSliderWidget,
256 262 value=4.5,
257 263 ),
258 264 )
259 265
260 266 def test_annotations():
261 267 @annotate(n=10, f=widgets.FloatTextWidget())
262 268 def f(n, f):
263 269 pass
264 270
265 271 c = interactive(f)
266 272 check_widgets(c,
267 273 n=dict(
268 274 cls=widgets.IntSliderWidget,
269 275 value=10,
270 276 ),
271 277 f=dict(
272 278 cls=widgets.FloatTextWidget,
273 279 ),
274 280 )
275 281
276 282 def test_priority():
277 283 @annotate(annotate='annotate', kwarg='annotate')
278 284 def f(kwarg='default', annotate='default', default='default'):
279 285 pass
280 286
281 287 c = interactive(f, kwarg='kwarg')
282 288 check_widgets(c,
283 289 kwarg=dict(
284 290 cls=widgets.TextWidget,
285 291 value='kwarg',
286 292 ),
287 293 annotate=dict(
288 294 cls=widgets.TextWidget,
289 295 value='annotate',
290 296 ),
291 297 )
292 298
293 299 @nt.with_setup(clear_display)
294 300 def test_decorator_kwarg():
295 301 with tt.monkeypatch(interaction, 'display', record_display):
296 302 @interact(a=5)
297 303 def foo(a):
298 304 pass
299 305 nt.assert_equal(len(displayed), 1)
300 306 w = displayed[0].children[0]
301 307 check_widget(w,
302 308 cls=widgets.IntSliderWidget,
303 309 value=5,
304 310 )
305 311
306 312 @nt.with_setup(clear_display)
307 313 def test_decorator_no_call():
308 314 with tt.monkeypatch(interaction, 'display', record_display):
309 315 @interact
310 316 def foo(a='default'):
311 317 pass
312 318 nt.assert_equal(len(displayed), 1)
313 319 w = displayed[0].children[0]
314 320 check_widget(w,
315 321 cls=widgets.TextWidget,
316 322 value='default',
317 323 )
318 324
319 325 @nt.with_setup(clear_display)
320 326 def test_call_interact():
321 327 def foo(a='default'):
322 328 pass
323 329 with tt.monkeypatch(interaction, 'display', record_display):
324 330 ifoo = interact(foo)
325 331 nt.assert_equal(len(displayed), 1)
326 332 w = displayed[0].children[0]
327 333 check_widget(w,
328 334 cls=widgets.TextWidget,
329 335 value='default',
330 336 )
331 337
332 338 @nt.with_setup(clear_display)
333 339 def test_call_interact_kwargs():
334 340 def foo(a='default'):
335 341 pass
336 342 with tt.monkeypatch(interaction, 'display', record_display):
337 343 ifoo = interact(foo, a=10)
338 344 nt.assert_equal(len(displayed), 1)
339 345 w = displayed[0].children[0]
340 346 check_widget(w,
341 347 cls=widgets.IntSliderWidget,
342 348 value=10,
343 349 )
344 350
345 351 @nt.with_setup(clear_display)
346 352 def test_call_decorated_on_trait_change():
347 353 """test calling @interact decorated functions"""
348 354 d = {}
349 355 with tt.monkeypatch(interaction, 'display', record_display):
350 356 @interact
351 357 def foo(a='default'):
352 358 d['a'] = a
353 359 return a
354 360 nt.assert_equal(len(displayed), 1)
355 361 w = displayed[0].children[0]
356 362 check_widget(w,
357 363 cls=widgets.TextWidget,
358 364 value='default',
359 365 )
360 366 # test calling the function directly
361 367 a = foo('hello')
362 368 nt.assert_equal(a, 'hello')
363 369 nt.assert_equal(d['a'], 'hello')
364 370
365 371 # test that setting trait values calls the function
366 372 w.value = 'called'
367 373 nt.assert_equal(d['a'], 'called')
368 374
369 375 @nt.with_setup(clear_display)
370 376 def test_call_decorated_kwargs_on_trait_change():
371 377 """test calling @interact(foo=bar) decorated functions"""
372 378 d = {}
373 379 with tt.monkeypatch(interaction, 'display', record_display):
374 380 @interact(a='kwarg')
375 381 def foo(a='default'):
376 382 d['a'] = a
377 383 return a
378 384 nt.assert_equal(len(displayed), 1)
379 385 w = displayed[0].children[0]
380 386 check_widget(w,
381 387 cls=widgets.TextWidget,
382 388 value='kwarg',
383 389 )
384 390 # test calling the function directly
385 391 a = foo('hello')
386 392 nt.assert_equal(a, 'hello')
387 393 nt.assert_equal(d['a'], 'hello')
388 394
389 395 # test that setting trait values calls the function
390 396 w.value = 'called'
391 397 nt.assert_equal(d['a'], 'called')
392 398
393 399 def test_fixed():
394 400 c = interactive(f, a=widgets.fixed(5), b='text')
395 401 nt.assert_equal(len(c.children), 1)
396 402 w = c.children[0]
397 403 check_widget(w,
398 404 cls=widgets.TextWidget,
399 405 value='text',
400 406 description='b',
401 407 )
402 408
@@ -1,60 +1,60 b''
1 1 """FloatWidget class.
2 2
3 3 Represents an unbounded float using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, CFloat, Bool, List, Enum
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class _FloatWidget(DOMWidget):
23 23 value = CFloat(0.0, help="Float value", sync=True)
24 24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
25 25 description = Unicode(help="Description of the value this widget represents", sync=True)
26 26
27 27
28 28 class _BoundedFloatWidget(_FloatWidget):
29 29 max = CFloat(100.0, help="Max value", sync=True)
30 30 min = CFloat(0.0, help="Min value", sync=True)
31 31 step = CFloat(0.1, help="Minimum step that the value can take (ignored by some views)", sync=True)
32 32
33 33 def __init__(self, *pargs, **kwargs):
34 34 """Constructor"""
35 35 DOMWidget.__init__(self, *pargs, **kwargs)
36 36 self.on_trait_change(self._validate, ['value', 'min', 'max'])
37 37
38 38 def _validate(self, name, old, new):
39 39 """Validate value, max, min."""
40 40 if self.min > new or new > self.max:
41 41 self.value = min(max(new, self.min), self.max)
42 42
43 43
44 44 class FloatTextWidget(_FloatWidget):
45 45 _view_name = Unicode('FloatTextView', sync=True)
46 46
47 47
48 48 class BoundedFloatTextWidget(_BoundedFloatWidget):
49 49 _view_name = Unicode('FloatTextView', sync=True)
50 50
51 51
52 52 class FloatSliderWidget(_BoundedFloatWidget):
53 53 _view_name = Unicode('FloatSliderView', sync=True)
54 54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57 57
58 58
59 59 class FloatProgressWidget(_BoundedFloatWidget):
60 60 _view_name = Unicode('ProgressView', sync=True)
@@ -1,60 +1,60 b''
1 1 """IntWidget class.
2 2
3 3 Represents an unbounded int using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, CInt, Bool, List, Enum
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class _IntWidget(DOMWidget):
23 23 value = CInt(0, help="Int value", sync=True)
24 24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
25 25 description = Unicode(help="Description of the value this widget represents", sync=True)
26 26
27 27
28 28 class _BoundedIntWidget(_IntWidget):
29 29 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
30 30 max = CInt(100, help="Max value", sync=True)
31 31 min = CInt(0, help="Min value", sync=True)
32 32
33 33 def __init__(self, *pargs, **kwargs):
34 34 """Constructor"""
35 35 DOMWidget.__init__(self, *pargs, **kwargs)
36 36 self.on_trait_change(self._validate, ['value', 'min', 'max'])
37 37
38 38 def _validate(self, name, old, new):
39 39 """Validate value, max, min."""
40 40 if self.min > new or new > self.max:
41 41 self.value = min(max(new, self.min), self.max)
42 42
43 43
44 44 class IntTextWidget(_IntWidget):
45 45 _view_name = Unicode('IntTextView', sync=True)
46 46
47 47
48 48 class BoundedIntTextWidget(_BoundedIntWidget):
49 49 _view_name = Unicode('IntTextView', sync=True)
50 50
51 51
52 52 class IntSliderWidget(_BoundedIntWidget):
53 53 _view_name = Unicode('IntSliderView', sync=True)
54 54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57 57
58 58
59 59 class IntProgressWidget(_BoundedIntWidget):
60 60 _view_name = Unicode('ProgressView', sync=True)
General Comments 0
You need to be logged in to leave comments. Login now