Skip to content
This repository was archived by the owner on Sep 28, 2022. It is now read-only.

Commit 27c304c

Browse files
author
Simon Biggs
committed
update detailed link
1 parent c7ebe3e commit 27c304c

File tree

2 files changed

+362
-5
lines changed

2 files changed

+362
-5
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ This should produce what is seen in the following screenshot:
140140

141141
For a markdown file that presents the majority of the features of scriptedforms
142142
see
143-
[detailed.md](https://raw.githubusercontent.com/SimonBiggs/scriptedforms/master/example/example/detailed.md).
143+
[detailed.form.md](https://raw.githubusercontent.com/SimonBiggs/scriptedforms/master/detailed.form.md).
144144
Try writing some of the contents of that file into a ScriptedForm to see how
145145
they work.
146146

@@ -152,16 +152,16 @@ By default only users on the local machine will be able to access the Jupyter No
152152

153153
Furthermore do not run a scripted form unless you trust its origin. Given the reactive nature of ScriptedForms, code within the markdown template can run on form opening, as well as during usage.
154154

155-
## Example that can be used as a template for deployment
155+
<!-- ## Example that can be used as a template for deployment
156156
157157
This is designed to be used as a quick and easy GUI for python packages. An
158158
example package that creates a console script that then uses scriptedforms to
159159
boot up a GUI can be found within the [example](./example) directory.
160160
161161
Within the [`README.md`](./example/README.md) file of that directory there is an
162-
explanation of how you might go about deploying your utility with its new GUI.
162+
explanation of how you might go about deploying your utility with its new GUI. -->
163163

164-
## [Optional] Installing the Jupyter Server extension
164+
<!-- ## [Optional] Installing the Jupyter Server extension
165165
166166
ScriptedForms can also be installed as a [Jupyter Server extension](http://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Distributing%20Jupyter%20Extensions%20as%20Python%20Packages.html#Enable-a-Server-Extension). Eventually this should allow the use of ScriptedForms with tools such as [JupyterHub](http://jupyterhub.readthedocs.io/en/latest/). This part of ScriptedForms is still a work in progress but if you want to give it a try then make sure you have at least version `0.5.15` of ScriptedForms and then run:
167167
@@ -173,7 +173,7 @@ Then to start ScriptedForms using its Jupyter Server extension run the following
173173
174174
```bash
175175
jupyter notebook --NotebookApp.default_url=/scriptedforms/use/quick-start.md
176-
```
176+
``` -->
177177

178178
## [Advanced users only] Installing scriptedforms from the GitHub source
179179

detailed.form.md

+357
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
<!-- markdownlint-disable MD033 -->
2+
3+
# A Demo Form
4+
5+
This is a detailed example demonstrating the usage of ScriptedForms.
6+
7+
To have this document help you the most ideally you should have it open both as
8+
a ScriptedForm and as a plain text document. If you open the document itself
9+
in a plain text editor (such as [Visual Studio Code](https://code.visualstudio.com/))
10+
then within the same directory as this document run `scriptedforms detailed.md`
11+
within a terminal you will be able to see the resulting form, and the syntax
12+
that produces it. You will also be able to edit the file and see the changes
13+
live within the ScriptedForm.
14+
15+
## Description
16+
17+
This file format is based upon markdown. There are however a few
18+
extra custom html elements. The custom html elements come in two
19+
types, either section elements `<section-something>` or
20+
variable elements `<variable-something>`.
21+
22+
## Custom elements overview
23+
24+
### Sections overview
25+
26+
#### Running Python code
27+
28+
Whenever python fenced code blocks are written within a section that code is
29+
no longer displayed within the document, instead it is sent to the Python
30+
kernel when certain conditions are fulfilled and inplace of where the code was
31+
written the output of that code is displayed. Code output is displayed as it
32+
would display within a Jupyter Notebook.
33+
34+
Python fenced code is written as follows:
35+
36+
```python
37+
print('Hello World!')
38+
```
39+
40+
#### Section types
41+
42+
There are four kinds of sections
43+
44+
* `<section-start>`,
45+
* `<section-live>`,
46+
* `<section-button>`,
47+
* and `<section-output>`.
48+
49+
Code which is written inside of these defined sections is run
50+
as python code according to specific rules.
51+
52+
### Variable overview
53+
54+
Variable elements are attached to a specific python variable which update on
55+
user input. All variable elements take just one item placed between the
56+
open and close braces. That item is
57+
the Python variable definition. It doesn't strictly have to be a Python variable
58+
it merely has to be valid Python code to exist on the left hand side of an assignment
59+
equal sign.
60+
61+
There are six kinds of variable inputs:
62+
63+
* `<variable-number>`,
64+
* `<variable-slider>`,
65+
* `<variable-table>`,
66+
* `<variable-tick>`,
67+
* `<variable-toggle>`,
68+
* `<variable-string>`,
69+
* and `<variable-dropdown>`.
70+
71+
`<variable-number>` and `<variable-slider>` represent floats or integers.
72+
`<variable-string>` represents a Python string. `<variable-tick>` and `<variable-toggle>`
73+
are both booleans. The `<variable-table>` is a pandas dataframe with all of the values
74+
in the dataframe being floats or integers. `<variable-dropdown>` is a string with provided options.
75+
76+
## Usage of the scriptedforms elements
77+
78+
### Start sections
79+
80+
Whenever a jupyterlab services session is started
81+
code within the start sections is run first.
82+
83+
If you reopen or update the form template without restarting the kernel
84+
this code will not re-run however a button will appear that will allow you to
85+
manually re-run the code if need be.
86+
87+
An example `<section-start>` is given following:
88+
89+
<section-start>
90+
91+
```python
92+
import time
93+
from IPython.display import display, Markdown
94+
95+
plt.rc('font', size=15)
96+
97+
data = np.ones(3) * np.nan
98+
data[0] = 5
99+
100+
table = pd.DataFrame(
101+
columns=['Meas1', 'Meas2', 'Meas3', 'Avg'],
102+
index=['6MV', '10MV'],
103+
data=[[1,np.nan,np.nan,np.nan],[4,5,np.nan,np.nan]])
104+
105+
hello = False
106+
world = False
107+
bye = False
108+
109+
machine = None
110+
111+
submit_count = 0
112+
output_count = 0
113+
114+
custom_machine = ''
115+
116+
display(Markdown('This is the output of a start section'))
117+
```
118+
119+
</section-start>
120+
121+
As can be seen from this code there are already a few namespaces included by
122+
default within the Python session. Some of these are for convenience, some are
123+
required for the proper running of the form. The code that is run at boot of
124+
a new form kernel can be found within the
125+
[source code](https://github.com/SimonBiggs/scriptedforms/blob/master/scriptedforms/src/app/form-builder-module/session-start-code.ts).
126+
127+
### Live sections and demo of each of the variable types
128+
129+
The `<section-live>` element is designed to contain both code and variable inputs. Whenever
130+
the user changes any variable within the live section all code that is also
131+
contained within that live section is subsequently run.
132+
133+
Each of the usable variables are demoed below making use of `<section-live>`.
134+
135+
#### Number and slider variables
136+
137+
Below is a `<section-live>` containing both `<variable-number>` and
138+
`<variable-slider>` elements. They are using a numpy array that has previously
139+
been defined within the `<section-start>`.
140+
141+
<section-live>
142+
<variable-number>data[0]</variable-number>
143+
<variable-number>data[1]</variable-number>
144+
145+
<variable-slider>data[0]</variable-slider>
146+
<variable-slider>data[1]</variable-slider>
147+
148+
```python
149+
plt.figure(figsize=(5*1.618,5))
150+
plt.plot(data, 'o');
151+
```
152+
153+
`<variable-number>` and `<variable-slider>` both have four optional parameters:
154+
155+
* `label`, for changing the visible label of the input
156+
* `min` and `max`, changing the range of the input
157+
* `step` for changing the step size of the input
158+
159+
Min and max defaults to `null` for `<variable-number>` and defaults to 0 and 100
160+
respectively for `<variable-slider>`. Step defaults to 1 for both elements.
161+
162+
The use of these optional parameters is demoed below:
163+
164+
<variable-number label="A custom label" min="0" max="10" step="0.1">data[2]</variable-number>
165+
<variable-slider label="A custom label" min="0" max="10" step="0.1">data[2]</variable-slider>
166+
167+
</section-live>
168+
169+
#### Example slider use case
170+
171+
Using the slider and live sections combined with matplotlib plots you can
172+
produce utilities like the following:
173+
174+
<section-start>
175+
176+
```python
177+
t = np.linspace(-2*np.pi, 2*np.pi, 500)
178+
omega = np.ones(2)
179+
```
180+
181+
</section-start>
182+
183+
<section-live>
184+
185+
Angular frequencies ($\omega$):
186+
187+
<variable-slider label="$\omega [0]$" min="0" max="6" step="0.1">omega[0]</variable-slider>
188+
<variable-slider label="$\omega [1]$" min="0" max="6" step="0.1">omega[1]</variable-slider>
189+
190+
```python
191+
plt.figure(figsize=(5*1.618,5))
192+
193+
oscillation = np.sin(t[:, np.newaxis] * omega[np.newaxis, :])
194+
summation = np.sum(oscillation, axis=1)
195+
196+
plt.plot(t, oscillation)
197+
plt.plot(t, summation)
198+
199+
plt.xlim([-2*np.pi, 2*np.pi])
200+
plt.ylim([-2.8, 2.8])
201+
plt.title('Two sin curves and their summation')
202+
plt.legend([
203+
r'$\omega [0] = {0:0.1f}$'.format(omega[0]),
204+
r'$\omega [1] = {0:0.1f}$'.format(omega[1]),
205+
'Summation'], loc='upper right')
206+
plt.xlabel('time (seconds)')
207+
plt.ylabel(r'$sin(\omega \times t)$');
208+
```
209+
210+
</section-live>
211+
212+
#### Table variables
213+
214+
Table variables display a full pandas dataframe. The live code can update one
215+
part of the table as other parts are being edited.
216+
217+
<section-live>
218+
<variable-table inputTypes="{'Meas1': 'number', 'Meas2': 'number', 'Meas3': 'number', 'Avg': 'readonly'}">table</variable-table>
219+
220+
```python
221+
table.iloc[:,3] = np.nanmean(table.iloc[:,0:3], axis=1)
222+
```
223+
224+
</section-live>
225+
226+
#### The tick and toggle variables
227+
228+
Tick and toggle variables are simply different representations of a True/False
229+
boolean variable within python. They are provided for use cases such as check
230+
lists and pass fail tests. These variables can interact with each other in
231+
interesting ways via the live Python code.
232+
233+
<section-live>
234+
<variable-tick>hello</variable-tick>
235+
236+
<variable-tick>world</variable-tick>
237+
238+
```python
239+
if bye:
240+
hello = False
241+
world = False
242+
243+
if hello and world:
244+
display(Markdown('Hello World!'))
245+
else:
246+
display(Markdown(''))
247+
```
248+
249+
<variable-toggle>bye</variable-toggle>
250+
</section-live>
251+
252+
#### String variables
253+
254+
String variables fill the entire width of the container they are in. They also
255+
expand when new lines are provied. An example use case is an optional notes
256+
field.
257+
258+
The Python code for this notes field takes what is written and renders it as
259+
markdown. Try writing `## Hello World!` and see what happens.
260+
261+
<section-live>
262+
<variable-string placeholder="write some notes here">notes</variable-string>
263+
264+
```python
265+
display(Markdown(notes))
266+
```
267+
268+
</section-live>
269+
270+
#### Dropdown variables
271+
272+
Dropdown allows options to be available in a dropdown list. To define the items
273+
used within the dropdown a Python list needs to be provided to the `items` html
274+
parameter. See below for how this works in practice.
275+
276+
<variable-string label="Your own machine name" placeholder="Write a custom machine name here">
277+
custom_machine
278+
</variable-string>
279+
280+
<section-live>
281+
282+
<variable-dropdown items="[1234, 2345, 'George', custom_machine]">machine</variable-dropdown>
283+
284+
```python
285+
print(machine)
286+
```
287+
288+
</section-live>
289+
290+
### Button sections
291+
292+
Button groups are designed for long running or standalone tasks that
293+
should not run whenever a user changes a variable.
294+
295+
They are defined as following:
296+
297+
<variable-string>notes</variable-string>
298+
299+
<section-button>
300+
301+
```python
302+
display(Markdown(notes))
303+
```
304+
305+
</section-button>
306+
307+
They will not run until their respective button is pressed.
308+
309+
#### Button customistion
310+
311+
Button sections are customisable, their content can be changed to words by
312+
changing the value property.
313+
314+
<section-button value="Submit">
315+
316+
```python
317+
submit_count += 1
318+
display(Markdown('Submitted {} times!'.format(submit_count)))
319+
```
320+
321+
</section-button>
322+
323+
Buttons can also be disabled using the conditional property. An example is the
324+
following button which is only enabled once the submit count becomes at least
325+
10.
326+
327+
<section-button inline value="Super Submit" conditional="submit_count >= 10">
328+
329+
```python
330+
display(Markdown('## Super Submit!!'))
331+
```
332+
333+
</section-button>
334+
335+
<section-button value="Slow button">
336+
337+
```python
338+
time.sleep(1)
339+
```
340+
341+
</section-button>
342+
343+
### Output sections
344+
345+
Code placed within output groups will run after any variable on the form
346+
changes in value.
347+
348+
<section-output>
349+
350+
```python
351+
output_count += 1
352+
print(output_count)
353+
354+
print(_scriptedforms_variable_handler.variables_json)
355+
```
356+
357+
</section-output>

0 commit comments

Comments
 (0)