##// END OF EJS Templates
Updated example notebooks
Jonathan Frederic -
Show More
@@ -1,202 +1,239 b''
1 {
1 {
2 "cells": [
2 "cells": [
3 {
3 {
4 "cell_type": "markdown",
4 "cell_type": "markdown",
5 "metadata": {},
5 "metadata": {},
6 "source": [
6 "source": [
7 "# Variable Inspector Widget"
7 "# Variable Inspector Widget"
8 ]
8 ]
9 },
9 },
10 {
10 {
11 "cell_type": "markdown",
11 "cell_type": "markdown",
12 "metadata": {},
12 "metadata": {},
13 "source": [
13 "source": [
14 "## A short example implementation"
14 "## A short example implementation"
15 ]
15 ]
16 },
16 },
17 {
17 {
18 "cell_type": "markdown",
18 "cell_type": "markdown",
19 "metadata": {},
19 "metadata": {},
20 "source": [
20 "source": [
21 "This notebook demonstrates how one can use the widgets already built-in to IPython to create a working variable inspector much like the ones seen in popular commercial scientific computing environments."
21 "This notebook demonstrates how one can use the widgets already built-in to IPython to create a working variable inspector much like the ones seen in popular commercial scientific computing environments."
22 ]
22 ]
23 },
23 },
24 {
24 {
25 "cell_type": "code",
25 "cell_type": "code",
26 "execution_count": null,
26 "execution_count": null,
27 "metadata": {
27 "metadata": {
28 "collapsed": false
28 "collapsed": false
29 },
29 },
30 "outputs": [],
30 "outputs": [],
31 "source": [
31 "source": [
32 "from IPython.html import widgets # Loads the Widget framework.\n",
32 "from IPython.html import widgets # Loads the Widget framework.\n",
33 "from IPython.core.magics.namespace import NamespaceMagics # Used to query namespace.\n",
33 "from IPython.core.magics.namespace import NamespaceMagics # Used to query namespace.\n",
34 "\n",
34 "\n",
35 "# For this example, hide these names, just to avoid polluting the namespace further\n",
35 "# For this example, hide these names, just to avoid polluting the namespace further\n",
36 "get_ipython().user_ns_hidden['widgets'] = widgets\n",
36 "get_ipython().user_ns_hidden['widgets'] = widgets\n",
37 "get_ipython().user_ns_hidden['NamespaceMagics'] = NamespaceMagics"
37 "get_ipython().user_ns_hidden['NamespaceMagics'] = NamespaceMagics"
38 ]
38 ]
39 },
39 },
40 {
40 {
41 "cell_type": "code",
41 "cell_type": "code",
42 "execution_count": null,
42 "execution_count": null,
43 "metadata": {
43 "metadata": {
44 "collapsed": false
44 "collapsed": false
45 },
45 },
46 "outputs": [],
46 "outputs": [],
47 "source": [
47 "source": [
48 "class VariableInspectorWindow(object):\n",
48 "class VariableInspectorWindow(object):\n",
49 " instance = None\n",
49 " instance = None\n",
50 " \n",
50 " \n",
51 " def __init__(self, ipython):\n",
51 " def __init__(self, ipython):\n",
52 " \"\"\"Public constructor.\"\"\"\n",
52 " \"\"\"Public constructor.\"\"\"\n",
53 " if VariableInspectorWindow.instance is not None:\n",
53 " if VariableInspectorWindow.instance is not None:\n",
54 " raise Exception(\"\"\"Only one instance of the Variable Inspector can exist at a \n",
54 " raise Exception(\"\"\"Only one instance of the Variable Inspector can exist at a \n",
55 " time. Call close() on the active instance before creating a new instance.\n",
55 " time. Call close() on the active instance before creating a new instance.\n",
56 " If you have lost the handle to the active instance, you can re-obtain it\n",
56 " If you have lost the handle to the active instance, you can re-obtain it\n",
57 " via `VariableInspectorWindow.instance`.\"\"\")\n",
57 " via `VariableInspectorWindow.instance`.\"\"\")\n",
58 " \n",
58 " \n",
59 " VariableInspectorWindow.instance = self\n",
59 " VariableInspectorWindow.instance = self\n",
60 " self.closed = False\n",
60 " self.closed = False\n",
61 " self.namespace = NamespaceMagics()\n",
61 " self.namespace = NamespaceMagics()\n",
62 " self.namespace.shell = ipython.kernel.shell\n",
62 " self.namespace.shell = ipython.kernel.shell\n",
63 " \n",
63 " \n",
64 " self._popout = widgets.Popup()\n",
64 " self._box = widgets.Box()\n",
65 " self._popout.description = \"Variable Inspector\"\n",
65 " self._box._dom_classes = ['inspector']\n",
66 " self._popout.button_text = self._popout.description\n",
66 " self._box.background_color = '#fff'\n",
67 " self._box.border_color = '#ccc'\n",
68 " self._box.border_width = 1\n",
69 " self._box.border_radius = 5\n",
67 "\n",
70 "\n",
68 " self._modal_body = widgets.VBox()\n",
71 " self._modal_body = widgets.VBox()\n",
69 " self._modal_body.overflow_y = 'scroll'\n",
72 " self._modal_body.overflow_y = 'scroll'\n",
70 "\n",
73 "\n",
71 " self._modal_body_label = widgets.HTML(value = 'Not hooked')\n",
74 " self._modal_body_label = widgets.HTML(value = 'Not hooked')\n",
72 " self._modal_body.children = [self._modal_body_label]\n",
75 " self._modal_body.children = [self._modal_body_label]\n",
73 "\n",
76 "\n",
74 " self._popout.children = [\n",
77 " self._box.children = [\n",
75 " self._modal_body, \n",
78 " self._modal_body, \n",
76 " ]\n",
79 " ]\n",
77 " \n",
80 " \n",
78 " self._ipython = ipython\n",
81 " self._ipython = ipython\n",
79 " self._ipython.events.register('post_run_cell', self._fill)\n",
82 " self._ipython.events.register('post_run_cell', self._fill)\n",
80 " \n",
83 " \n",
81 " def close(self):\n",
84 " def close(self):\n",
82 " \"\"\"Close and remove hooks.\"\"\"\n",
85 " \"\"\"Close and remove hooks.\"\"\"\n",
83 " if not self.closed:\n",
86 " if not self.closed:\n",
84 " self._ipython.events.unregister('post_run_cell', self._fill)\n",
87 " self._ipython.events.unregister('post_run_cell', self._fill)\n",
85 " self._popout.close()\n",
88 " self._box.close()\n",
86 " self.closed = True\n",
89 " self.closed = True\n",
87 " VariableInspectorWindow.instance = None\n",
90 " VariableInspectorWindow.instance = None\n",
88 "\n",
91 "\n",
89 " def _fill(self):\n",
92 " def _fill(self):\n",
90 " \"\"\"Fill self with variable information.\"\"\"\n",
93 " \"\"\"Fill self with variable information.\"\"\"\n",
91 " values = self.namespace.who_ls()\n",
94 " values = self.namespace.who_ls()\n",
92 " self._modal_body_label.value = '<table class=\"table table-bordered table-striped\"><tr><th>Name</th><th>Type</th><th>Value</th></tr><tr><td>' + \\\n",
95 " self._modal_body_label.value = '<table class=\"table table-bordered table-striped\"><tr><th>Name</th><th>Type</th><th>Value</th></tr><tr><td>' + \\\n",
93 " '</td></tr><tr><td>'.join(['{0}</td><td>{1}</td><td>{2}'.format(v, type(eval(v)).__name__, str(eval(v))) for v in values]) + \\\n",
96 " '</td></tr><tr><td>'.join(['{0}</td><td>{1}</td><td>{2}'.format(v, type(eval(v)).__name__, str(eval(v))) for v in values]) + \\\n",
94 " '</td></tr></table>'\n",
97 " '</td></tr></table>'\n",
95 "\n",
98 "\n",
96 " def _ipython_display_(self):\n",
99 " def _ipython_display_(self):\n",
97 " \"\"\"Called when display() or pyout is used to display the Variable \n",
100 " \"\"\"Called when display() or pyout is used to display the Variable \n",
98 " Inspector.\"\"\"\n",
101 " Inspector.\"\"\"\n",
99 " self._popout._ipython_display_()\n"
102 " self._box._ipython_display_()\n"
100 ]
103 ]
101 },
104 },
102 {
105 {
103 "cell_type": "code",
106 "cell_type": "code",
104 "execution_count": null,
107 "execution_count": null,
105 "metadata": {
108 "metadata": {
106 "collapsed": false
109 "collapsed": false
107 },
110 },
108 "outputs": [],
111 "outputs": [],
109 "source": [
112 "source": [
110 "inspector = VariableInspectorWindow(get_ipython())\n",
113 "inspector = VariableInspectorWindow(get_ipython())\n",
111 "inspector"
114 "inspector"
112 ]
115 ]
113 },
116 },
114 {
117 {
115 "cell_type": "markdown",
118 "cell_type": "markdown",
116 "metadata": {},
119 "metadata": {},
117 "source": [
120 "source": [
121 "Pop the inspector out of the widget area using Javascript. To close the inspector, click the close button on the widget area that it was spawned from."
122 ]
123 },
124 {
125 "cell_type": "code",
126 "execution_count": null,
127 "metadata": {
128 "collapsed": false
129 },
130 "outputs": [],
131 "source": [
132 "%%javascript\n",
133 "$('div.inspector')\n",
134 " .detach()\n",
135 " .prependTo($('body'))\n",
136 " .css({\n",
137 " 'z-index': 999, \n",
138 " position: 'fixed',\n",
139 " 'box-shadow': '5px 5px 12px -3px black',\n",
140 " opacity: 0.9\n",
141 " })\n",
142 " .draggable();"
143 ]
144 },
145 {
146 "cell_type": "markdown",
147 "metadata": {},
148 "source": [
118 "# Test"
149 "# Test"
119 ]
150 ]
120 },
151 },
121 {
152 {
122 "cell_type": "code",
153 "cell_type": "code",
123 "execution_count": null,
154 "execution_count": null,
124 "metadata": {
155 "metadata": {
125 "collapsed": false
156 "collapsed": false
126 },
157 },
127 "outputs": [],
158 "outputs": [],
128 "source": [
159 "source": [
129 "a = 5"
160 "a = 5"
130 ]
161 ]
131 },
162 },
132 {
163 {
133 "cell_type": "code",
164 "cell_type": "code",
134 "execution_count": null,
165 "execution_count": null,
135 "metadata": {
166 "metadata": {
136 "collapsed": false
167 "collapsed": false
137 },
168 },
138 "outputs": [],
169 "outputs": [],
139 "source": [
170 "source": [
140 "b = 3.0"
171 "b = 3.0"
141 ]
172 ]
142 },
173 },
143 {
174 {
144 "cell_type": "code",
175 "cell_type": "code",
145 "execution_count": null,
176 "execution_count": null,
146 "metadata": {
177 "metadata": {
147 "collapsed": false
178 "collapsed": false
148 },
179 },
149 "outputs": [],
180 "outputs": [],
150 "source": [
181 "source": [
151 "c = a * b"
182 "c = a * b"
152 ]
183 ]
153 },
184 },
154 {
185 {
155 "cell_type": "code",
186 "cell_type": "code",
156 "execution_count": null,
187 "execution_count": null,
157 "metadata": {
188 "metadata": {
158 "collapsed": false
189 "collapsed": false
159 },
190 },
160 "outputs": [],
191 "outputs": [],
161 "source": [
192 "source": [
162 "d = \"String\""
193 "d = \"String\""
163 ]
194 ]
164 },
195 },
165 {
196 {
166 "cell_type": "code",
197 "cell_type": "code",
167 "execution_count": null,
198 "execution_count": null,
168 "metadata": {
199 "metadata": {
169 "collapsed": false
200 "collapsed": false
170 },
201 },
171 "outputs": [],
202 "outputs": [],
172 "source": [
203 "source": [
173 "del b"
204 "del b"
174 ]
205 ]
175 },
206 },
176 {
207 {
177 "cell_type": "code",
208 "cell_type": "code",
178 "execution_count": null,
209 "execution_count": null,
179 "metadata": {
210 "metadata": {
180 "collapsed": false
211 "collapsed": false
181 },
212 },
182 "outputs": [],
213 "outputs": [],
183 "source": [
214 "source": [
184 "inspector.close()"
215 "inspector.close()"
185 ]
216 ]
186 }
217 }
187 ],
218 ],
188 "metadata": {
219 "metadata": {
189 "kernelspec": {
220 "kernelspec": {
221 "display_name": "IPython (Python 2)",
222 "name": "python2"
223 },
224 "language_info": {
190 "codemirror_mode": {
225 "codemirror_mode": {
191 "name": "python",
226 "name": "ipython",
192 "version": 2
227 "version": 2
193 },
228 },
194 "display_name": "Python 2",
229 "file_extension": ".py",
195 "language": "python",
230 "mimetype": "text/x-python",
196 "name": "python2"
231 "name": "python",
197 },
232 "nbconvert_exporter": "python",
198 "signature": "sha256:474731659fb14b86672d1dafb2b497fa280082ab40a8a82fe2cde1b6d9b88a6e"
233 "pygments_lexer": "ipython2",
234 "version": "2.7.6"
235 }
199 },
236 },
200 "nbformat": 4,
237 "nbformat": 4,
201 "nbformat_minor": 0
238 "nbformat_minor": 0
202 } No newline at end of file
239 }
@@ -1,775 +1,584 b''
1 {
1 {
2 "cells": [
2 "cells": [
3 {
3 {
4 "cell_type": "markdown",
4 "cell_type": "markdown",
5 "metadata": {},
5 "metadata": {},
6 "source": [
6 "source": [
7 "[Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb)"
7 "[Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb)"
8 ]
8 ]
9 },
9 },
10 {
10 {
11 "cell_type": "code",
11 "cell_type": "code",
12 "execution_count": null,
12 "execution_count": null,
13 "metadata": {
13 "metadata": {
14 "collapsed": false
14 "collapsed": false
15 },
15 },
16 "outputs": [],
16 "outputs": [],
17 "source": [
17 "source": [
18 "%%html\n",
18 "%%html\n",
19 "<style>\n",
19 "<style>\n",
20 ".example-container { background: #999999; padding: 2px; min-height: 100px; }\n",
20 ".example-container { background: #999999; padding: 2px; min-height: 100px; }\n",
21 ".example-container.sm { min-height: 50px; }\n",
21 ".example-container.sm { min-height: 50px; }\n",
22 ".example-box { background: #9999FF; width: 50px; height: 50px; text-align: center; vertical-align: middle; color: white; font-weight: bold; margin: 2px;}\n",
22 ".example-box { background: #9999FF; width: 50px; height: 50px; text-align: center; vertical-align: middle; color: white; font-weight: bold; margin: 2px;}\n",
23 ".example-box.med { width: 65px; height: 65px; } \n",
23 ".example-box.med { width: 65px; height: 65px; } \n",
24 ".example-box.lrg { width: 80px; height: 80px; } \n",
24 ".example-box.lrg { width: 80px; height: 80px; } \n",
25 "</style>"
25 "</style>"
26 ]
26 ]
27 },
27 },
28 {
28 {
29 "cell_type": "code",
29 "cell_type": "code",
30 "execution_count": null,
30 "execution_count": null,
31 "metadata": {
31 "metadata": {
32 "collapsed": false
32 "collapsed": false
33 },
33 },
34 "outputs": [],
34 "outputs": [],
35 "source": [
35 "source": [
36 "from IPython.html import widgets\n",
36 "from IPython.html import widgets\n",
37 "from IPython.display import display"
37 "from IPython.display import display"
38 ]
38 ]
39 },
39 },
40 {
40 {
41 "cell_type": "markdown",
41 "cell_type": "markdown",
42 "metadata": {
42 "metadata": {
43 "slideshow": {
43 "slideshow": {
44 "slide_type": "slide"
44 "slide_type": "slide"
45 }
45 }
46 },
46 },
47 "source": [
47 "source": [
48 "# Widget Styling"
48 "# Widget Styling"
49 ]
49 ]
50 },
50 },
51 {
51 {
52 "cell_type": "markdown",
52 "cell_type": "markdown",
53 "metadata": {},
53 "metadata": {},
54 "source": [
54 "source": [
55 "## Basic styling"
55 "## Basic styling"
56 ]
56 ]
57 },
57 },
58 {
58 {
59 "cell_type": "markdown",
59 "cell_type": "markdown",
60 "metadata": {},
60 "metadata": {},
61 "source": [
61 "source": [
62 "The widgets distributed with IPython can be styled by setting the following traits:\n",
62 "The widgets distributed with IPython can be styled by setting the following traits:\n",
63 "\n",
63 "\n",
64 "- width \n",
64 "- width \n",
65 "- height \n",
65 "- height \n",
66 "- fore_color \n",
66 "- fore_color \n",
67 "- back_color \n",
67 "- back_color \n",
68 "- border_color \n",
68 "- border_color \n",
69 "- border_width \n",
69 "- border_width \n",
70 "- border_style \n",
70 "- border_style \n",
71 "- font_style \n",
71 "- font_style \n",
72 "- font_weight \n",
72 "- font_weight \n",
73 "- font_size \n",
73 "- font_size \n",
74 "- font_family \n",
74 "- font_family \n",
75 "\n",
75 "\n",
76 "The example below shows how a `Button` widget can be styled:"
76 "The example below shows how a `Button` widget can be styled:"
77 ]
77 ]
78 },
78 },
79 {
79 {
80 "cell_type": "code",
80 "cell_type": "code",
81 "execution_count": null,
81 "execution_count": null,
82 "metadata": {
82 "metadata": {
83 "collapsed": false
83 "collapsed": false
84 },
84 },
85 "outputs": [],
85 "outputs": [],
86 "source": [
86 "source": [
87 "button = widgets.Button(\n",
87 "button = widgets.Button(\n",
88 " description='Hello World!',\n",
88 " description='Hello World!',\n",
89 " width=100, # Integers are interpreted as pixel measurements.\n",
89 " width=100, # Integers are interpreted as pixel measurements.\n",
90 " height='2em', # em is valid HTML unit of measurement.\n",
90 " height='2em', # em is valid HTML unit of measurement.\n",
91 " color='lime', # Colors can be set by name,\n",
91 " color='lime', # Colors can be set by name,\n",
92 " background_color='#0022FF', # and also by color code.\n",
92 " background_color='#0022FF', # and also by color code.\n",
93 " border_color='red')\n",
93 " border_color='red')\n",
94 "display(button)"
94 "display(button)"
95 ]
95 ]
96 },
96 },
97 {
97 {
98 "cell_type": "markdown",
98 "cell_type": "markdown",
99 "metadata": {
99 "metadata": {
100 "slideshow": {
100 "slideshow": {
101 "slide_type": "slide"
101 "slide_type": "slide"
102 }
102 }
103 },
103 },
104 "source": [
104 "source": [
105 "## Parent/child relationships"
105 "## Parent/child relationships"
106 ]
106 ]
107 },
107 },
108 {
108 {
109 "cell_type": "markdown",
109 "cell_type": "markdown",
110 "metadata": {},
110 "metadata": {},
111 "source": [
111 "source": [
112 "To display widget A inside widget B, widget A must be a child of widget B. Widgets that can contain other widgets have a **`children` attribute**. This attribute can be **set via a keyword argument** in the widget's constructor **or after construction**. Calling display on an **object with children automatically displays those children**, too."
112 "To display widget A inside widget B, widget A must be a child of widget B. Widgets that can contain other widgets have a **`children` attribute**. This attribute can be **set via a keyword argument** in the widget's constructor **or after construction**. Calling display on an **object with children automatically displays those children**, too."
113 ]
113 ]
114 },
114 },
115 {
115 {
116 "cell_type": "code",
116 "cell_type": "code",
117 "execution_count": null,
117 "execution_count": null,
118 "metadata": {
118 "metadata": {
119 "collapsed": false
119 "collapsed": false
120 },
120 },
121 "outputs": [],
121 "outputs": [],
122 "source": [
122 "source": [
123 "from IPython.display import display\n",
123 "from IPython.display import display\n",
124 "\n",
124 "\n",
125 "float_range = widgets.FloatSlider()\n",
125 "float_range = widgets.FloatSlider()\n",
126 "string = widgets.Text(value='hi')\n",
126 "string = widgets.Text(value='hi')\n",
127 "container = widgets.Box(children=[float_range, string])\n",
127 "container = widgets.Box(children=[float_range, string])\n",
128 "\n",
128 "\n",
129 "container.border_color = 'red'\n",
129 "container.border_color = 'red'\n",
130 "container.border_style = 'dotted'\n",
130 "container.border_style = 'dotted'\n",
131 "container.border_width = 3\n",
131 "container.border_width = 3\n",
132 "display(container) # Displays the `container` and all of it's children."
132 "display(container) # Displays the `container` and all of it's children."
133 ]
133 ]
134 },
134 },
135 {
135 {
136 "cell_type": "markdown",
136 "cell_type": "markdown",
137 "metadata": {},
137 "metadata": {},
138 "source": [
138 "source": [
139 "### After the parent is displayed"
139 "### After the parent is displayed"
140 ]
140 ]
141 },
141 },
142 {
142 {
143 "cell_type": "markdown",
143 "cell_type": "markdown",
144 "metadata": {
144 "metadata": {
145 "slideshow": {
145 "slideshow": {
146 "slide_type": "slide"
146 "slide_type": "slide"
147 }
147 }
148 },
148 },
149 "source": [
149 "source": [
150 "Children **can be added to parents** after the parent has been displayed. The **parent is responsible for rendering its children**."
150 "Children **can be added to parents** after the parent has been displayed. The **parent is responsible for rendering its children**."
151 ]
151 ]
152 },
152 },
153 {
153 {
154 "cell_type": "code",
154 "cell_type": "code",
155 "execution_count": null,
155 "execution_count": null,
156 "metadata": {
156 "metadata": {
157 "collapsed": false
157 "collapsed": false
158 },
158 },
159 "outputs": [],
159 "outputs": [],
160 "source": [
160 "source": [
161 "container = widgets.Box()\n",
161 "container = widgets.Box()\n",
162 "container.border_color = 'red'\n",
162 "container.border_color = 'red'\n",
163 "container.border_style = 'dotted'\n",
163 "container.border_style = 'dotted'\n",
164 "container.border_width = 3\n",
164 "container.border_width = 3\n",
165 "display(container)\n",
165 "display(container)\n",
166 "\n",
166 "\n",
167 "int_range = widgets.IntSlider()\n",
167 "int_range = widgets.IntSlider()\n",
168 "container.children=[int_range]"
168 "container.children=[int_range]"
169 ]
169 ]
170 },
170 },
171 {
171 {
172 "cell_type": "markdown",
172 "cell_type": "markdown",
173 "metadata": {
173 "metadata": {
174 "slideshow": {
174 "slideshow": {
175 "slide_type": "slide"
175 "slide_type": "slide"
176 }
176 }
177 },
177 },
178 "source": [
178 "source": [
179 "## Fancy boxes"
179 "## Fancy boxes"
180 ]
180 ]
181 },
181 },
182 {
182 {
183 "cell_type": "markdown",
183 "cell_type": "markdown",
184 "metadata": {},
184 "metadata": {},
185 "source": [
185 "source": [
186 "If you need to display a more complicated set of widgets, there are **specialized containers** that you can use. To display **multiple sets of widgets**, you can use an **`Accordion` or a `Tab` in combination with one `Box` per set of widgets** (as seen below). The \"pages\" of these widgets are their children. To set the titles of the pages, one must **call `set_title` after the widget has been displayed**."
186 "If you need to display a more complicated set of widgets, there are **specialized containers** that you can use. To display **multiple sets of widgets**, you can use an **`Accordion` or a `Tab` in combination with one `Box` per set of widgets** (as seen below). The \"pages\" of these widgets are their children. To set the titles of the pages, one must **call `set_title` after the widget has been displayed**."
187 ]
187 ]
188 },
188 },
189 {
189 {
190 "cell_type": "markdown",
190 "cell_type": "markdown",
191 "metadata": {},
191 "metadata": {},
192 "source": [
192 "source": [
193 "### Accordion"
193 "### Accordion"
194 ]
194 ]
195 },
195 },
196 {
196 {
197 "cell_type": "code",
197 "cell_type": "code",
198 "execution_count": null,
198 "execution_count": null,
199 "metadata": {
199 "metadata": {
200 "collapsed": false
200 "collapsed": false
201 },
201 },
202 "outputs": [],
202 "outputs": [],
203 "source": [
203 "source": [
204 "name1 = widgets.Text(description='Location:')\n",
204 "name1 = widgets.Text(description='Location:')\n",
205 "zip1 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
205 "zip1 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
206 "page1 = widgets.Box(children=[name1, zip1])\n",
206 "page1 = widgets.Box(children=[name1, zip1])\n",
207 "\n",
207 "\n",
208 "name2 = widgets.Text(description='Location:')\n",
208 "name2 = widgets.Text(description='Location:')\n",
209 "zip2 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
209 "zip2 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
210 "page2 = widgets.Box(children=[name2, zip2])\n",
210 "page2 = widgets.Box(children=[name2, zip2])\n",
211 "\n",
211 "\n",
212 "accord = widgets.Accordion(children=[page1, page2])\n",
212 "accord = widgets.Accordion(children=[page1, page2])\n",
213 "display(accord)\n",
213 "display(accord)\n",
214 "\n",
214 "\n",
215 "accord.set_title(0, 'From')\n",
215 "accord.set_title(0, 'From')\n",
216 "accord.set_title(1, 'To')"
216 "accord.set_title(1, 'To')"
217 ]
217 ]
218 },
218 },
219 {
219 {
220 "cell_type": "markdown",
220 "cell_type": "markdown",
221 "metadata": {
221 "metadata": {
222 "slideshow": {
222 "slideshow": {
223 "slide_type": "slide"
223 "slide_type": "slide"
224 }
224 }
225 },
225 },
226 "source": [
226 "source": [
227 "### TabWidget"
227 "### TabWidget"
228 ]
228 ]
229 },
229 },
230 {
230 {
231 "cell_type": "code",
231 "cell_type": "code",
232 "execution_count": null,
232 "execution_count": null,
233 "metadata": {
233 "metadata": {
234 "collapsed": false
234 "collapsed": false
235 },
235 },
236 "outputs": [],
236 "outputs": [],
237 "source": [
237 "source": [
238 "name = widgets.Text(description='Name:')\n",
238 "name = widgets.Text(description='Name:')\n",
239 "color = widgets.Dropdown(description='Color:', values=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])\n",
239 "color = widgets.Dropdown(description='Color:', values=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])\n",
240 "page1 = widgets.Box(children=[name, color])\n",
240 "page1 = widgets.Box(children=[name, color])\n",
241 "\n",
241 "\n",
242 "age = widgets.IntSlider(description='Age:', min=0, max=120, value=50)\n",
242 "age = widgets.IntSlider(description='Age:', min=0, max=120, value=50)\n",
243 "gender = widgets.RadioButtons(description='Gender:', values=['male', 'female'])\n",
243 "gender = widgets.RadioButtons(description='Gender:', values=['male', 'female'])\n",
244 "page2 = widgets.Box(children=[age, gender])\n",
244 "page2 = widgets.Box(children=[age, gender])\n",
245 "\n",
245 "\n",
246 "tabs = widgets.Tab(children=[page1, page2])\n",
246 "tabs = widgets.Tab(children=[page1, page2])\n",
247 "display(tabs)\n",
247 "display(tabs)\n",
248 "\n",
248 "\n",
249 "tabs.set_title(0, 'Name')\n",
249 "tabs.set_title(0, 'Name')\n",
250 "tabs.set_title(1, 'Details')"
250 "tabs.set_title(1, 'Details')"
251 ]
251 ]
252 },
252 },
253 {
253 {
254 "cell_type": "markdown",
254 "cell_type": "markdown",
255 "metadata": {
255 "metadata": {
256 "slideshow": {
256 "slideshow": {
257 "slide_type": "slide"
257 "slide_type": "slide"
258 }
258 }
259 },
259 },
260 "source": [
260 "source": [
261 "### Popup"
262 ]
263 },
264 {
265 "cell_type": "markdown",
266 "metadata": {},
267 "source": [
268 "Unlike the other two special containers, the `Popup` is only **designed to display one set of widgets**. The `Popup` can be used to **display widgets outside of the widget area**. "
269 ]
270 },
271 {
272 "cell_type": "code",
273 "execution_count": null,
274 "metadata": {
275 "collapsed": false
276 },
277 "outputs": [],
278 "source": [
279 "counter = widgets.IntText(description='Counter:')\n",
280 "popup = widgets.Popup(children=[counter], description='Popup Demo', button_text='Popup Button')\n",
281 "display(popup)"
282 ]
283 },
284 {
285 "cell_type": "code",
286 "execution_count": null,
287 "metadata": {
288 "collapsed": false
289 },
290 "outputs": [],
291 "source": [
292 "counter.value += 1"
293 ]
294 },
295 {
296 "cell_type": "code",
297 "execution_count": null,
298 "metadata": {
299 "collapsed": false
300 },
301 "outputs": [],
302 "source": []
303 },
304 {
305 "cell_type": "code",
306 "execution_count": null,
307 "metadata": {
308 "collapsed": false
309 },
310 "outputs": [],
311 "source": []
312 },
313 {
314 "cell_type": "code",
315 "execution_count": null,
316 "metadata": {
317 "collapsed": false
318 },
319 "outputs": [],
320 "source": []
321 },
322 {
323 "cell_type": "code",
324 "execution_count": null,
325 "metadata": {
326 "collapsed": false
327 },
328 "outputs": [],
329 "source": []
330 },
331 {
332 "cell_type": "code",
333 "execution_count": null,
334 "metadata": {
335 "collapsed": false
336 },
337 "outputs": [],
338 "source": []
339 },
340 {
341 "cell_type": "code",
342 "execution_count": null,
343 "metadata": {
344 "collapsed": false
345 },
346 "outputs": [],
347 "source": []
348 },
349 {
350 "cell_type": "code",
351 "execution_count": null,
352 "metadata": {
353 "collapsed": false
354 },
355 "outputs": [],
356 "source": []
357 },
358 {
359 "cell_type": "code",
360 "execution_count": null,
361 "metadata": {
362 "collapsed": false
363 },
364 "outputs": [],
365 "source": []
366 },
367 {
368 "cell_type": "code",
369 "execution_count": null,
370 "metadata": {
371 "collapsed": false
372 },
373 "outputs": [],
374 "source": []
375 },
376 {
377 "cell_type": "code",
378 "execution_count": null,
379 "metadata": {
380 "collapsed": false
381 },
382 "outputs": [],
383 "source": []
384 },
385 {
386 "cell_type": "code",
387 "execution_count": null,
388 "metadata": {
389 "collapsed": false
390 },
391 "outputs": [],
392 "source": []
393 },
394 {
395 "cell_type": "code",
396 "execution_count": null,
397 "metadata": {
398 "collapsed": false
399 },
400 "outputs": [],
401 "source": []
402 },
403 {
404 "cell_type": "code",
405 "execution_count": null,
406 "metadata": {
407 "collapsed": false
408 },
409 "outputs": [],
410 "source": []
411 },
412 {
413 "cell_type": "code",
414 "execution_count": null,
415 "metadata": {
416 "collapsed": false
417 },
418 "outputs": [],
419 "source": []
420 },
421 {
422 "cell_type": "code",
423 "execution_count": null,
424 "metadata": {
425 "collapsed": false
426 },
427 "outputs": [],
428 "source": [
429 "counter.value += 1"
430 ]
431 },
432 {
433 "cell_type": "code",
434 "execution_count": null,
435 "metadata": {
436 "collapsed": false
437 },
438 "outputs": [],
439 "source": [
440 "popup.close()"
441 ]
442 },
443 {
444 "cell_type": "markdown",
445 "metadata": {
446 "slideshow": {
447 "slide_type": "slide"
448 }
449 },
450 "source": [
451 "# Alignment"
261 "# Alignment"
452 ]
262 ]
453 },
263 },
454 {
264 {
455 "cell_type": "markdown",
265 "cell_type": "markdown",
456 "metadata": {},
266 "metadata": {},
457 "source": [
267 "source": [
458 "Most widgets have a **`description` attribute**, which allows a label for the widget to be defined.\n",
268 "Most widgets have a **`description` attribute**, which allows a label for the widget to be defined.\n",
459 "The label of the widget **has a fixed minimum width**.\n",
269 "The label of the widget **has a fixed minimum width**.\n",
460 "The text of the label is **always right aligned and the widget is left aligned**:"
270 "The text of the label is **always right aligned and the widget is left aligned**:"
461 ]
271 ]
462 },
272 },
463 {
273 {
464 "cell_type": "code",
274 "cell_type": "code",
465 "execution_count": null,
275 "execution_count": null,
466 "metadata": {
276 "metadata": {
467 "collapsed": false
277 "collapsed": false
468 },
278 },
469 "outputs": [],
279 "outputs": [],
470 "source": [
280 "source": [
471 "display(widgets.Text(description=\"a:\"))\n",
281 "display(widgets.Text(description=\"a:\"))\n",
472 "display(widgets.Text(description=\"aa:\"))\n",
282 "display(widgets.Text(description=\"aa:\"))\n",
473 "display(widgets.Text(description=\"aaa:\"))"
283 "display(widgets.Text(description=\"aaa:\"))"
474 ]
284 ]
475 },
285 },
476 {
286 {
477 "cell_type": "markdown",
287 "cell_type": "markdown",
478 "metadata": {
288 "metadata": {
479 "slideshow": {
289 "slideshow": {
480 "slide_type": "slide"
290 "slide_type": "slide"
481 }
291 }
482 },
292 },
483 "source": [
293 "source": [
484 "If a **label is longer** than the minimum width, the **widget is shifted to the right**:"
294 "If a **label is longer** than the minimum width, the **widget is shifted to the right**:"
485 ]
295 ]
486 },
296 },
487 {
297 {
488 "cell_type": "code",
298 "cell_type": "code",
489 "execution_count": null,
299 "execution_count": null,
490 "metadata": {
300 "metadata": {
491 "collapsed": false
301 "collapsed": false
492 },
302 },
493 "outputs": [],
303 "outputs": [],
494 "source": [
304 "source": [
495 "display(widgets.Text(description=\"a:\"))\n",
305 "display(widgets.Text(description=\"a:\"))\n",
496 "display(widgets.Text(description=\"aa:\"))\n",
306 "display(widgets.Text(description=\"aa:\"))\n",
497 "display(widgets.Text(description=\"aaa:\"))\n",
307 "display(widgets.Text(description=\"aaa:\"))\n",
498 "display(widgets.Text(description=\"aaaaaaaaaaaaaaaaaa:\"))"
308 "display(widgets.Text(description=\"aaaaaaaaaaaaaaaaaa:\"))"
499 ]
309 ]
500 },
310 },
501 {
311 {
502 "cell_type": "markdown",
312 "cell_type": "markdown",
503 "metadata": {
313 "metadata": {
504 "slideshow": {
314 "slideshow": {
505 "slide_type": "slide"
315 "slide_type": "slide"
506 }
316 }
507 },
317 },
508 "source": [
318 "source": [
509 "If a `description` is **not set** for the widget, the **label is not displayed**:"
319 "If a `description` is **not set** for the widget, the **label is not displayed**:"
510 ]
320 ]
511 },
321 },
512 {
322 {
513 "cell_type": "code",
323 "cell_type": "code",
514 "execution_count": null,
324 "execution_count": null,
515 "metadata": {
325 "metadata": {
516 "collapsed": false
326 "collapsed": false
517 },
327 },
518 "outputs": [],
328 "outputs": [],
519 "source": [
329 "source": [
520 "display(widgets.Text(description=\"a:\"))\n",
330 "display(widgets.Text(description=\"a:\"))\n",
521 "display(widgets.Text(description=\"aa:\"))\n",
331 "display(widgets.Text(description=\"aa:\"))\n",
522 "display(widgets.Text(description=\"aaa:\"))\n",
332 "display(widgets.Text(description=\"aaa:\"))\n",
523 "display(widgets.Text())"
333 "display(widgets.Text())"
524 ]
334 ]
525 },
335 },
526 {
336 {
527 "cell_type": "markdown",
337 "cell_type": "markdown",
528 "metadata": {
338 "metadata": {
529 "slideshow": {
339 "slideshow": {
530 "slide_type": "slide"
340 "slide_type": "slide"
531 }
341 }
532 },
342 },
533 "source": [
343 "source": [
534 "## Flex boxes"
344 "## Flex boxes"
535 ]
345 ]
536 },
346 },
537 {
347 {
538 "cell_type": "markdown",
348 "cell_type": "markdown",
539 "metadata": {},
349 "metadata": {},
540 "source": [
350 "source": [
541 "Widgets can be aligned using the `FlexBox`, `HBox`, and `VBox` widgets."
351 "Widgets can be aligned using the `FlexBox`, `HBox`, and `VBox` widgets."
542 ]
352 ]
543 },
353 },
544 {
354 {
545 "cell_type": "markdown",
355 "cell_type": "markdown",
546 "metadata": {
356 "metadata": {
547 "slideshow": {
357 "slideshow": {
548 "slide_type": "slide"
358 "slide_type": "slide"
549 }
359 }
550 },
360 },
551 "source": [
361 "source": [
552 "### Application to widgets"
362 "### Application to widgets"
553 ]
363 ]
554 },
364 },
555 {
365 {
556 "cell_type": "markdown",
366 "cell_type": "markdown",
557 "metadata": {},
367 "metadata": {},
558 "source": [
368 "source": [
559 "Widgets display vertically by default:"
369 "Widgets display vertically by default:"
560 ]
370 ]
561 },
371 },
562 {
372 {
563 "cell_type": "code",
373 "cell_type": "code",
564 "execution_count": null,
374 "execution_count": null,
565 "metadata": {
375 "metadata": {
566 "collapsed": false
376 "collapsed": false
567 },
377 },
568 "outputs": [],
378 "outputs": [],
569 "source": [
379 "source": [
570 "buttons = [widgets.Button(description=str(i)) for i in range(3)]\n",
380 "buttons = [widgets.Button(description=str(i)) for i in range(3)]\n",
571 "display(*buttons)"
381 "display(*buttons)"
572 ]
382 ]
573 },
383 },
574 {
384 {
575 "cell_type": "markdown",
385 "cell_type": "markdown",
576 "metadata": {
386 "metadata": {
577 "slideshow": {
387 "slideshow": {
578 "slide_type": "slide"
388 "slide_type": "slide"
579 }
389 }
580 },
390 },
581 "source": [
391 "source": [
582 "### Using hbox"
392 "### Using hbox"
583 ]
393 ]
584 },
394 },
585 {
395 {
586 "cell_type": "markdown",
396 "cell_type": "markdown",
587 "metadata": {},
397 "metadata": {},
588 "source": [
398 "source": [
589 "To make widgets display horizontally, you need to **child them to a `HBox` widget**."
399 "To make widgets display horizontally, you need to **child them to a `HBox` widget**."
590 ]
400 ]
591 },
401 },
592 {
402 {
593 "cell_type": "code",
403 "cell_type": "code",
594 "execution_count": null,
404 "execution_count": null,
595 "metadata": {
405 "metadata": {
596 "collapsed": false
406 "collapsed": false
597 },
407 },
598 "outputs": [],
408 "outputs": [],
599 "source": [
409 "source": [
600 "container = widgets.HBox(children=buttons)\n",
410 "container = widgets.HBox(children=buttons)\n",
601 "display(container)"
411 "display(container)"
602 ]
412 ]
603 },
413 },
604 {
414 {
605 "cell_type": "markdown",
415 "cell_type": "markdown",
606 "metadata": {},
416 "metadata": {},
607 "source": [
417 "source": [
608 "By setting the width of the container to 100% and its `pack` to `center`, you can center the buttons."
418 "By setting the width of the container to 100% and its `pack` to `center`, you can center the buttons."
609 ]
419 ]
610 },
420 },
611 {
421 {
612 "cell_type": "code",
422 "cell_type": "code",
613 "execution_count": null,
423 "execution_count": null,
614 "metadata": {
424 "metadata": {
615 "collapsed": false
425 "collapsed": false
616 },
426 },
617 "outputs": [],
427 "outputs": [],
618 "source": [
428 "source": [
619 "container.width = '100%'\n",
429 "container.width = '100%'\n",
620 "container.pack = 'center'"
430 "container.pack = 'center'"
621 ]
431 ]
622 },
432 },
623 {
433 {
624 "cell_type": "markdown",
434 "cell_type": "markdown",
625 "metadata": {
435 "metadata": {
626 "slideshow": {
436 "slideshow": {
627 "slide_type": "slide"
437 "slide_type": "slide"
628 }
438 }
629 },
439 },
630 "source": [
440 "source": [
631 "## Visibility"
441 "## Visibility"
632 ]
442 ]
633 },
443 },
634 {
444 {
635 "cell_type": "markdown",
445 "cell_type": "markdown",
636 "metadata": {},
446 "metadata": {},
637 "source": [
447 "source": [
638 "Sometimes it is necessary to **hide or show widgets** in place, **without having to re-display** the widget.\n",
448 "Sometimes it is necessary to **hide or show widgets** in place, **without having to re-display** the widget.\n",
639 "The `visible` property of widgets can be used to hide or show **widgets that have already been displayed** (as seen below). The `visible` property can be:\n",
449 "The `visible` property of widgets can be used to hide or show **widgets that have already been displayed** (as seen below). The `visible` property can be:\n",
640 "* `True` - the widget is displayed\n",
450 "* `True` - the widget is displayed\n",
641 "* `False` - the widget is hidden, and the empty space where the widget would be is collapsed\n",
451 "* `False` - the widget is hidden, and the empty space where the widget would be is collapsed\n",
642 "* `None` - the widget is hidden, and the empty space where the widget would be is shown"
452 "* `None` - the widget is hidden, and the empty space where the widget would be is shown"
643 ]
453 ]
644 },
454 },
645 {
455 {
646 "cell_type": "code",
456 "cell_type": "code",
647 "execution_count": null,
457 "execution_count": null,
648 "metadata": {
458 "metadata": {
649 "collapsed": false
459 "collapsed": false
650 },
460 },
651 "outputs": [],
461 "outputs": [],
652 "source": [
462 "source": [
653 "w1 = widgets.Latex(value=\"First line\")\n",
463 "w1 = widgets.Latex(value=\"First line\")\n",
654 "w2 = widgets.Latex(value=\"Second line\")\n",
464 "w2 = widgets.Latex(value=\"Second line\")\n",
655 "w3 = widgets.Latex(value=\"Third line\")\n",
465 "w3 = widgets.Latex(value=\"Third line\")\n",
656 "display(w1, w2, w3)"
466 "display(w1, w2, w3)"
657 ]
467 ]
658 },
468 },
659 {
469 {
660 "cell_type": "code",
470 "cell_type": "code",
661 "execution_count": null,
471 "execution_count": null,
662 "metadata": {
472 "metadata": {
663 "collapsed": true
473 "collapsed": true
664 },
474 },
665 "outputs": [],
475 "outputs": [],
666 "source": [
476 "source": [
667 "w2.visible=None"
477 "w2.visible=None"
668 ]
478 ]
669 },
479 },
670 {
480 {
671 "cell_type": "code",
481 "cell_type": "code",
672 "execution_count": null,
482 "execution_count": null,
673 "metadata": {
483 "metadata": {
674 "collapsed": false
484 "collapsed": false
675 },
485 },
676 "outputs": [],
486 "outputs": [],
677 "source": [
487 "source": [
678 "w2.visible=False"
488 "w2.visible=False"
679 ]
489 ]
680 },
490 },
681 {
491 {
682 "cell_type": "code",
492 "cell_type": "code",
683 "execution_count": null,
493 "execution_count": null,
684 "metadata": {
494 "metadata": {
685 "collapsed": false
495 "collapsed": false
686 },
496 },
687 "outputs": [],
497 "outputs": [],
688 "source": [
498 "source": [
689 "w2.visible=True"
499 "w2.visible=True"
690 ]
500 ]
691 },
501 },
692 {
502 {
693 "cell_type": "markdown",
503 "cell_type": "markdown",
694 "metadata": {
504 "metadata": {
695 "slideshow": {
505 "slideshow": {
696 "slide_type": "slide"
506 "slide_type": "slide"
697 }
507 }
698 },
508 },
699 "source": [
509 "source": [
700 "### Another example"
510 "### Another example"
701 ]
511 ]
702 },
512 },
703 {
513 {
704 "cell_type": "markdown",
514 "cell_type": "markdown",
705 "metadata": {},
515 "metadata": {},
706 "source": [
516 "source": [
707 "In the example below, a form is rendered, which conditionally displays widgets depending on the state of other widgets. Try toggling the student checkbox."
517 "In the example below, a form is rendered, which conditionally displays widgets depending on the state of other widgets. Try toggling the student checkbox."
708 ]
518 ]
709 },
519 },
710 {
520 {
711 "cell_type": "code",
521 "cell_type": "code",
712 "execution_count": null,
522 "execution_count": null,
713 "metadata": {
523 "metadata": {
714 "collapsed": false
524 "collapsed": false
715 },
525 },
716 "outputs": [],
526 "outputs": [],
717 "source": [
527 "source": [
718 "form = widgets.VBox()\n",
528 "form = widgets.VBox()\n",
719 "first = widgets.Text(description=\"First Name:\")\n",
529 "first = widgets.Text(description=\"First Name:\")\n",
720 "last = widgets.Text(description=\"Last Name:\")\n",
530 "last = widgets.Text(description=\"Last Name:\")\n",
721 "\n",
531 "\n",
722 "student = widgets.Checkbox(description=\"Student:\", value=False)\n",
532 "student = widgets.Checkbox(description=\"Student:\", value=False)\n",
723 "school_info = widgets.VBox(visible=False, children=[\n",
533 "school_info = widgets.VBox(visible=False, children=[\n",
724 " widgets.Text(description=\"School:\"),\n",
534 " widgets.Text(description=\"School:\"),\n",
725 " widgets.IntText(description=\"Grade:\", min=0, max=12)\n",
535 " widgets.IntText(description=\"Grade:\", min=0, max=12)\n",
726 " ])\n",
536 " ])\n",
727 "\n",
537 "\n",
728 "pet = widgets.Text(description=\"Pet's Name:\")\n",
538 "pet = widgets.Text(description=\"Pet's Name:\")\n",
729 "form.children = [first, last, student, school_info, pet]\n",
539 "form.children = [first, last, student, school_info, pet]\n",
730 "display(form)\n",
540 "display(form)\n",
731 "\n",
541 "\n",
732 "def on_student_toggle(name, value):\n",
542 "def on_student_toggle(name, value):\n",
733 " if value:\n",
543 " if value:\n",
734 " school_info.visible = True\n",
544 " school_info.visible = True\n",
735 " else:\n",
545 " else:\n",
736 " school_info.visible = False\n",
546 " school_info.visible = False\n",
737 "student.on_trait_change(on_student_toggle, 'value')\n"
547 "student.on_trait_change(on_student_toggle, 'value')\n"
738 ]
548 ]
739 },
549 },
740 {
550 {
741 "cell_type": "markdown",
551 "cell_type": "markdown",
742 "metadata": {},
552 "metadata": {},
743 "source": [
553 "source": [
744 "[Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb)"
554 "[Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb)"
745 ]
555 ]
746 }
556 }
747 ],
557 ],
748 "metadata": {
558 "metadata": {
749 "cell_tags": [
559 "cell_tags": [
750 [
560 [
751 "<None>",
561 "<None>",
752 null
562 null
753 ]
563 ]
754 ],
564 ],
755 "kernelspec": {
565 "kernelspec": {
756 "display_name": "Python 2",
566 "display_name": "IPython (Python 2)",
757 "name": "python2"
567 "name": "python2"
758 },
568 },
759 "language_info": {
569 "language_info": {
760 "codemirror_mode": {
570 "codemirror_mode": {
761 "name": "ipython",
571 "name": "ipython",
762 "version": 2
572 "version": 2
763 },
573 },
764 "file_extension": ".py",
574 "file_extension": ".py",
765 "mimetype": "text/x-python",
575 "mimetype": "text/x-python",
766 "name": "python",
576 "name": "python",
767 "nbconvert_exporter": "python",
577 "nbconvert_exporter": "python",
768 "pygments_lexer": "ipython2",
578 "pygments_lexer": "ipython2",
769 "version": "2.7.8"
579 "version": "2.7.6"
770 },
580 }
771 "signature": "sha256:198630bf2c2eb00401b60a395ebc75049099864b62f0faaf416da02f9808c40b"
772 },
581 },
773 "nbformat": 4,
582 "nbformat": 4,
774 "nbformat_minor": 0
583 "nbformat_minor": 0
775 } No newline at end of file
584 }
General Comments 0
You need to be logged in to leave comments. Login now