├── .gitignore
├── .nojekyll
├── README.md
└── doc
├── pub
├── ._part0000_web4sa_django.html
├── ._part0000_web4sa_flask.html
├── ._part0000_web4sa_plain.html
├── ._part0001_web4sa_django.html
├── ._part0001_web4sa_flask.html
├── ._part0001_web4sa_plain.html
├── ._part0002_web4sa_django.html
├── ._part0002_web4sa_flask.html
├── ._part0002_web4sa_plain.html
├── ._part0003_web4sa_django.html
├── ._part0003_web4sa_flask.html
├── ._part0003_web4sa_plain.html
├── ._part0004_web4sa_django.html
├── ._part0004_web4sa_flask.html
├── ._part0004_web4sa_plain.html
├── ._part0005_web4sa_django.html
├── ._part0005_web4sa_flask.html
├── ._part0005_web4sa_plain.html
├── ._part0006_web4sa_django.html
├── ._part0006_web4sa_flask.html
├── ._part0006_web4sa_plain.html
├── ._part0007_web4sa_django.html
├── ._part0007_web4sa_flask.html
├── ._part0007_web4sa_plain.html
├── ._part0008_web4sa_django.html
├── ._part0008_web4sa_flask.html
├── ._part0008_web4sa_plain.html
├── ._part0009_web4sa_django.html
├── ._part0009_web4sa_flask.html
├── ._part0009_web4sa_plain.html
├── ._part0010_web4sa_flask.html
├── ._part0010_web4sa_plain.html
├── ._part0011_web4sa_flask.html
├── ._part0011_web4sa_plain.html
├── ._part0012_web4sa_flask.html
├── ._part0012_web4sa_plain.html
├── ._part0013_web4sa_plain.html
├── ._part0014_web4sa_plain.html
├── ._part0015_web4sa_plain.html
├── ._part0016_web4sa_plain.html
├── ._part0017_web4sa_plain.html
├── ._web4sa_django000.html
├── ._web4sa_django001.html
├── ._web4sa_django002.html
├── ._web4sa_django003.html
├── ._web4sa_django004.html
├── ._web4sa_django005.html
├── ._web4sa_django006.html
├── ._web4sa_django007.html
├── ._web4sa_django008.html
├── ._web4sa_flask000.html
├── ._web4sa_flask001.html
├── ._web4sa_flask002.html
├── ._web4sa_flask003.html
├── ._web4sa_flask004.html
├── ._web4sa_flask005.html
├── ._web4sa_flask006.html
├── ._web4sa_flask007.html
├── ._web4sa_flask008.html
├── ._web4sa_flask009.html
├── ._web4sa_flask010.html
├── ._web4sa_flask011.html
├── ._web4sa_flask012.html
├── ._web4sa_flask013.html
├── ._web4sa_flask014.html
├── ._web4sa_flask015.html
├── ._web4sa_flask016.html
├── ._web4sa_flask017.html
├── ._web4sa_plain000.html
├── ._web4sa_plain001.html
├── ._web4sa_plain002.html
├── ._web4sa_plain003.html
├── ._web4sa_plain004.html
├── ._web4sa_plain005.html
├── ._web4sa_plain006.html
├── ._web4sa_plain007.html
├── ._web4sa_plain008.html
├── ._web4sa_plain009.html
├── ._web4sa_plain010.html
├── ._web4sa_plain011.html
├── ._web4sa_plain012.html
├── ._web4sa_plain013.html
├── ._web4sa_plain014.html
├── ._web4sa_plain015.html
├── ._web4sa_plain016.html
├── ._web4sa_plain017.html
├── ._web4sa_plain018.html
├── ._web4sa_plain019.html
├── ._web4sa_plain020.html
├── ._web4sa_plain021.html
├── ._web4sa_solarized000.html
├── ._web4sa_solarized001.html
├── ._web4sa_solarized002.html
├── ._web4sa_solarized003.html
├── ._web4sa_solarized004.html
├── ._web4sa_solarized005.html
├── ._web4sa_solarized006.html
├── ._web4sa_solarized007.html
├── ._web4sa_solarized008.html
├── ._web4sa_solarized009.html
├── ._web4sa_solarized010.html
├── ._web4sa_solarized011.html
├── ._web4sa_solarized012.html
├── ._web4sa_solarized013.html
├── ._web4sa_solarized014.html
├── ._web4sa_solarized015.html
├── ._web4sa_solarized016.html
├── ._web4sa_solarized017.html
├── ._web4sa_solarized018.html
├── ._web4sa_solarized019.html
├── ._web4sa_solarized020.html
├── ._web4sa_solarized021.html
├── fig-web4sa
│ ├── Taylor_approx.png
│ ├── Taylor_approx_exp2t.pdf
│ ├── Taylor_approx_exp2t.png
│ ├── gen_flask_gamma.png
│ ├── hw1_django_input.png
│ ├── hw1_django_output.png
│ ├── hw1_flask_input.png
│ ├── hw1_flask_output.png
│ ├── hw2_django_output.png
│ ├── hw2_flask_output.png
│ ├── login_login.png
│ ├── login_main.png
│ ├── login_old.png
│ ├── login_register.png
│ ├── login_results.png
│ ├── plot_formula.png
│ ├── upload1.png
│ ├── upload2.png
│ ├── upload3.png
│ ├── vib1_flask_bootstrap.png
│ ├── vib1_flask_bootswatch_journal.png
│ ├── vib1_flask_error1.png
│ ├── vib1_flask_input.png
│ ├── vib1_flask_latex.png
│ ├── vib1_flask_output.png
│ ├── vib1_flask_table2.png
│ ├── vib2_flask_error1.png
│ └── vib3_flask_gamma.png
├── index.html
├── sphinx-cbc
│ ├── ._web4sa000.html
│ ├── ._web4sa001.html
│ ├── .buildinfo
│ ├── _images
│ │ ├── hw1_django_input.png
│ │ ├── hw1_django_output.png
│ │ ├── hw1_flask_input.png
│ │ ├── hw1_flask_output.png
│ │ ├── hw2_django_output.png
│ │ ├── hw2_flask_output.png
│ │ ├── vib1_flask_error1.png
│ │ ├── vib1_flask_input.png
│ │ ├── vib1_flask_latex.png
│ │ ├── vib1_flask_output.png
│ │ ├── vib1_flask_table2.png
│ │ └── vib2_flask_error1.png
│ ├── _sources
│ │ ├── ._web4sa000.txt
│ │ ├── ._web4sa001.txt
│ │ └── index.txt
│ ├── _static
│ │ ├── ajax-loader.gif
│ │ ├── basic.css
│ │ ├── cbc_banner.png
│ │ ├── cbc_logo.png
│ │ ├── comment-bright.png
│ │ ├── comment-close.png
│ │ ├── comment.png
│ │ ├── default.css
│ │ ├── doctools.js
│ │ ├── down-pressed.png
│ │ ├── down.png
│ │ ├── file.png
│ │ ├── jquery.js
│ │ ├── minus.png
│ │ ├── plus.png
│ │ ├── pygments.css
│ │ ├── searchtools.js
│ │ ├── sidebar.js
│ │ ├── underscore.js
│ │ ├── up-pressed.png
│ │ ├── up.png
│ │ └── websupport.js
│ ├── genindex.html
│ ├── index.html
│ ├── objects.inv
│ ├── search.html
│ └── searchindex.js
├── web4sa.html
├── web4sa.pdf
├── web4sa_django.html
├── web4sa_flask.html
├── web4sa_plain.html
├── web4sa_plain_all.html
└── web4sa_solarized.html
├── src
└── web4sa
│ ├── clean.sh
│ ├── django_hw.do.txt
│ ├── django_vib.do.txt
│ ├── exer
│ ├── Taylor_approx
│ │ ├── compute.py
│ │ ├── controller.py
│ │ ├── model.py
│ │ └── templates
│ │ │ └── view.html
│ ├── addmul
│ │ ├── compute.py
│ │ ├── controller.py
│ │ └── model.py
│ ├── gen_ext
│ │ ├── compute.py
│ │ ├── controller.py
│ │ ├── model.py
│ │ ├── templates
│ │ │ ├── view.html
│ │ │ ├── view_results.html
│ │ │ └── view_results_default.py
│ │ └── view.py
│ └── plot_formula
│ │ ├── README.txt
│ │ ├── compute.py
│ │ ├── controller.py
│ │ ├── model.py
│ │ └── templates
│ │ └── view.html
│ ├── exercises.do.txt
│ ├── fig-web4sa
│ ├── Taylor_approx.png
│ ├── Taylor_approx_exp2t.pdf
│ ├── Taylor_approx_exp2t.png
│ ├── gen_flask_gamma.png
│ ├── hw1_django_input.png
│ ├── hw1_django_output.png
│ ├── hw1_flask_input.png
│ ├── hw1_flask_output.png
│ ├── hw2_django_output.png
│ ├── hw2_flask_output.png
│ ├── login_main.png
│ ├── login_register.png
│ ├── plot_formula.png
│ ├── upload1.png
│ ├── upload2.png
│ ├── upload3.png
│ ├── vib1_flask_bootstrap.png
│ ├── vib1_flask_bootswatch_journal.png
│ ├── vib1_flask_error1.png
│ ├── vib1_flask_input.png
│ ├── vib1_flask_latex.png
│ ├── vib1_flask_output.png
│ ├── vib1_flask_table2.png
│ └── vib2_flask_error1.png
│ ├── flask_hw.do.txt
│ ├── flask_vib.do.txt
│ ├── html_templates
│ ├── template_django.html
│ ├── template_flask.html
│ └── template_flask_django.html
│ ├── index.do.txt
│ ├── intro.do.txt
│ ├── links.do.txt
│ ├── make.sh
│ ├── publish.sh
│ ├── slides-web4sa
│ ├── django_hw.do.txt
│ ├── django_vib.do.txt
│ ├── flask_hw.do.txt
│ ├── flask_vib.do.txt
│ ├── intro.do.txt
│ └── links.do.txt
│ ├── slides_web4sa.do.txt
│ ├── src-web4sa
│ ├── apps
│ │ ├── django_apps
│ │ │ ├── hw1
│ │ │ │ ├── __init__.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── models.py
│ │ │ │ ├── templates
│ │ │ │ │ └── hw1.html
│ │ │ │ ├── tests.py
│ │ │ │ └── views.py
│ │ │ ├── hw2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── models.py
│ │ │ │ ├── templates
│ │ │ │ │ └── hw2.html
│ │ │ │ └── views.py
│ │ │ ├── vib1
│ │ │ │ ├── __init__.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── models.py
│ │ │ │ ├── templates
│ │ │ │ │ └── vib1.html
│ │ │ │ └── views.py
│ │ │ └── vib2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── models.py
│ │ │ │ ├── templates
│ │ │ │ └── vib2.html
│ │ │ │ └── views.py
│ │ ├── flask_apps
│ │ │ ├── gen
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── model.py
│ │ │ │ └── templates
│ │ │ │ │ ├── view.html
│ │ │ │ │ ├── view_results.html
│ │ │ │ │ └── view_results_default.html
│ │ │ ├── hw1
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ └── templates
│ │ │ │ │ ├── view_input.html
│ │ │ │ │ └── view_output.html
│ │ │ ├── hw2
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ └── templates
│ │ │ │ │ └── view.html
│ │ │ ├── hw3
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── model.py
│ │ │ │ └── templates
│ │ │ │ │ └── view.html
│ │ │ ├── login
│ │ │ │ ├── _generate_app.py
│ │ │ │ ├── app.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── db_models.py
│ │ │ │ └── forms.py
│ │ │ ├── upload
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── model.py
│ │ │ │ └── testfile.dat
│ │ │ ├── vib1
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── model.py
│ │ │ │ ├── static
│ │ │ │ │ └── basic.css
│ │ │ │ └── templates
│ │ │ │ │ ├── view.html
│ │ │ │ │ ├── view_bootstrap.html
│ │ │ │ │ ├── view_css.html
│ │ │ │ │ ├── view_errcheck.html
│ │ │ │ │ ├── view_flask_bootstrap.html
│ │ │ │ │ ├── view_plain.html
│ │ │ │ │ ├── view_table.html
│ │ │ │ │ └── view_tex.html
│ │ │ ├── vib2
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ ├── model.py
│ │ │ │ └── templates
│ │ │ │ │ └── view.html
│ │ │ └── vib3
│ │ │ │ ├── compute.py
│ │ │ │ ├── controller.py
│ │ │ │ └── model.py
│ │ └── py_apps
│ │ │ ├── hw_mvc
│ │ │ ├── compute.py
│ │ │ ├── controller.py
│ │ │ ├── model.py
│ │ │ └── view.py
│ │ │ └── hw_orig
│ │ │ └── hw.py
│ └── django_project
│ │ ├── django_project
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ │ └── manage.py
│ └── web4sa.do.txt
└── web
├── images
├── body-bg.png
├── highlight-bg.jpg
├── hr.png
├── octocat-icon.png
├── tar-gz-icon.png
└── zip-icon.png
├── index.html
├── javascripts
└── main.js
├── params.json
└── stylesheets
├── print.css
├── pygment_trac.css
└── stylesheet.css
/.gitignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 | # compiled files:
3 | *.o
4 | *.so
5 | *.a
6 | # temporary files:
7 | build
8 | *.bak
9 | *.swp
10 | *~
11 | .*~
12 | *.old
13 | tmp*
14 | temp*
15 | .#*
16 | \#*
17 | # tex files:
18 | *.log
19 | *.dvi
20 | *.aux
21 | *.blg
22 | *.bbl
23 | *.idx
24 | *.ilg
25 | *.ind
26 | *.loe
27 | *.nav
28 | *.out
29 | *.toc
30 | *.snm
31 | *.vrb
32 | # eclipse files:
33 | *.cproject
34 | *.project
35 | # misc:
36 | .DS_Store
37 | .idea
38 | __pycache__
39 | _minted-*
40 | # doconce:
41 | .*_html_file_collection
42 | .*.exerinfo
43 | .*.copyright
44 | sphinx-rootdir
45 | Trash
46 |
--------------------------------------------------------------------------------
/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/.nojekyll
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | web4sciapps
2 | ===========
3 |
4 | Examples on using web frameworks for making scientific applications.
--------------------------------------------------------------------------------
/doc/pub/._part0005_web4sa_plain.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
36 |
37 |
38 |
39 |
129 |
130 |
131 |
132 |
133 |
134 |
142 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
Troubleshooting
163 |
164 |
165 | Address already in use.
166 | You can easily kill the Flask application and restart it, but sometimes
167 | you will get an error that the address is already in use.
168 | To recover from this problem, run the lsof
program to see which program
169 | that applies the 5000 port (Flask runs its server on http://127.0.0.1:5000
,
170 | which means that it uses the 5000 port). Find the PID of the program
171 | that occupies the port and force abortion of that program:
172 |
173 |
174 |
175 |
176 |
Terminal> lsof -i :5000
177 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
178 | python 48824 hpl 3u IPv4 1128848 0t0 TCP ...
179 | Terminal> kill -9 48824
180 |
181 |
182 | You are now ready to restart a Flask application.
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
--------------------------------------------------------------------------------
/doc/pub/._part0008_web4sa_django.html:
--------------------------------------------------------------------------------
1 |
2 |
31 |
32 |
33 |
34 |
35 |
36 |
44 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
Exercises
60 |
61 |
62 |
63 |
64 |
Exercise 1: Add two numbers
65 |
66 |
67 | Make a web application that reads two numbers from a web page,
68 | adds the numbers, and prints the sum in a new web page.
69 | Package the necessary files that constitute the application
70 | in a tar file.
71 | Filename: add2.tar.gz
.
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/doc/pub/._web4sa_django002.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 | Using Django for Scientific Web Applications
20 |
21 |
22 |
34 |
35 |
36 |
37 |
38 |
50 |
51 |
52 |
53 |
54 |
104 |
105 |
106 |
107 |
108 |
109 |
117 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
A very simple application
127 |
128 |
129 | We shall start with the simplest possible application,
130 | a "scientific hello world program", where the
131 | task is to read a number and write out "Hello, World!" followed by
132 | the sine of the number. This application has one input variable and
133 | a line of text as output.
134 |
135 |
136 | Our first implementation reads the input from the command
137 | line and writes the results to the terminal window:
138 |
139 |
140 |
141 |
142 |
#!/usr/bin/env python
143 | import sys , math
144 | r = float (sys. argv[1 ])
145 | s = math. sin(r)
146 | print 'Hello, World! sin( %g )= %g ' % (r, s)
147 |
148 |
149 | In the terminal we can exemplify the program
150 |
151 |
152 |
153 |
154 |
Terminal> python hw.py 1.2
155 | Hello, World! sin(1.2)=0.932039
156 |
157 |
158 | The task of the web version of this program is to read the r
159 | variable from a web page, compute the sine,
160 | and write out a new web page with the resulting text.
161 |
162 |
163 |
164 |
165 |
173 |
174 |
175 |
176 |
177 |
178 |
184 |
185 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/doc/pub/._web4sa_django007.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 | Using Django for Scientific Web Applications
20 |
21 |
22 |
34 |
35 |
36 |
37 |
38 |
50 |
51 |
52 |
53 |
54 |
104 |
105 |
106 |
107 |
108 |
109 |
117 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
Resources
127 |
128 |
129 | Below are some resources for accounts and login with Django as well as
130 | utilization of Bootstrap styles in the views.
131 |
132 |
139 |
140 |
141 |
142 |
150 |
151 |
152 |
153 |
154 |
155 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/Taylor_approx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/Taylor_approx.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/Taylor_approx_exp2t.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/Taylor_approx_exp2t.pdf
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/Taylor_approx_exp2t.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/Taylor_approx_exp2t.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/gen_flask_gamma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/gen_flask_gamma.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw1_django_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw1_django_input.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw1_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw1_django_output.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw1_flask_input.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw1_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw2_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw2_django_output.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/hw2_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/hw2_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/login_login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/login_login.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/login_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/login_main.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/login_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/login_old.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/login_register.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/login_register.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/login_results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/login_results.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/plot_formula.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/plot_formula.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/upload1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/upload1.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/upload2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/upload2.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/upload3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/upload3.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_bootstrap.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_bootswatch_journal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_bootswatch_journal.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_error1.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_input.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_latex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_latex.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib1_flask_table2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib1_flask_table2.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib2_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib2_flask_error1.png
--------------------------------------------------------------------------------
/doc/pub/fig-web4sa/vib3_flask_gamma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/fig-web4sa/vib3_flask_gamma.png
--------------------------------------------------------------------------------
/doc/pub/index.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Using Web Frameworks for Scientific Applications
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
Using Web Frameworks for Scientific Applications
38 |
39 |
40 |
41 |
42 |
43 | Hans Petter Langtangen [1]
44 |
45 |
46 |
47 | Anders Johansen [2]
48 |
49 |
50 |
51 |
52 |
53 |
[1] Center for Biomedical Computing, Simula Research Laboratory and Department of Informatics, University of Oslo
54 |
[2] Center for Biomedical Computing, Simula Research Laboratory
55 |
56 |
57 |
Oct 11, 2015
58 |
59 |
60 |
61 |
62 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/._web4sa000.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Using Web Frameworks for Scientific Applications
11 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
57 |
58 |
59 |
60 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
Using Web Frameworks for Scientific Applications
83 |
84 |
85 |
86 |
87 | Authors: Hans Petter Langtangen, Anders E. Johansen
88 |
89 | Date: Oct 11, 2015
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
134 |
135 |
136 |
151 |
152 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: 55852d421c7b5dd40a3eb6329928b707
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw1_django_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw1_django_input.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw1_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw1_django_output.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw1_flask_input.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw1_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw2_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw2_django_output.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/hw2_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/hw2_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib1_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib1_flask_error1.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib1_flask_input.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib1_flask_latex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib1_flask_latex.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib1_flask_output.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib1_flask_table2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib1_flask_table2.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_images/vib2_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_images/vib2_flask_error1.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_sources/._web4sa000.txt:
--------------------------------------------------------------------------------
1 | .. Automatically generated Sphinx-extended reStructuredText file from DocOnce source
2 | (https://github.com/hplgit/doconce/)
3 |
4 | .. Document title:
5 |
6 | Using Web Frameworks for Scientific Applications
7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8 |
9 | :Authors: Hans Petter Langtangen, Anders E. Johansen
10 | :Date: Oct 11, 2015
11 |
12 |
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_sources/index.txt:
--------------------------------------------------------------------------------
1 |
2 | .. Master file automatically created by doconce sphinx_dir
3 |
4 | Using Web Frameworks for Scientific Applications
5 | ================================================
6 |
7 | Contents:
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 |
12 | ._web4sa000
13 | ._web4sa001
14 | ._web4sa002
15 | ._web4sa003
16 | ._web4sa004
17 | ._web4sa005
18 | ._web4sa006
19 | ._web4sa007
20 |
21 |
22 | Index
23 | =====
24 |
25 | * :ref:`genindex`
26 |
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/ajax-loader.gif
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/cbc_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/cbc_banner.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/cbc_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/cbc_logo.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/comment-bright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/comment-bright.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/comment-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/comment-close.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/comment.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/default.css:
--------------------------------------------------------------------------------
1 | /*
2 | * default.css_t
3 | * ~~~~~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- default theme.
6 | *
7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | @import url("basic.css");
13 |
14 | /* -- page layout ----------------------------------------------------------- */
15 |
16 | body {
17 | font-family: sans-serif;
18 | font-size: 100%;
19 | background-color: #ffffff;
20 | color: #000;
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | div.document {
26 | background-color: #ffffff;
27 | }
28 |
29 | div.documentwrapper {
30 | float: left;
31 | width: 100%;
32 | }
33 |
34 | div.bodywrapper {
35 | margin: 0 0 0 230px;
36 | }
37 |
38 | div.body {
39 | background-color: #ffffff;
40 | color: #000000;
41 | padding: 0 20px 30px 20px;
42 | }
43 | div.bodywrapper {
44 | margin: 0 230px 0 0;
45 | }
46 |
47 | div.footer {
48 | color: #8A0808;
49 | width: 100%;
50 | padding: 9px 0 9px 0;
51 | text-align: center;
52 | font-size: 75%;
53 | }
54 |
55 | div.footer a {
56 | color: #8A0808;
57 | text-decoration: underline;
58 | }
59 |
60 | div.related {
61 | background-color: #666666;
62 | line-height: 30px;
63 | color: #ffffff;
64 | }
65 |
66 | div.related a {
67 | color: #ffffff;
68 | }
69 |
70 | div.sphinxsidebar {
71 | float: right;
72 | }
73 |
74 | div.sphinxsidebar h3 {
75 | font-family: 'Trebuchet MS', sans-serif;
76 | color: #8A0808;
77 | font-size: 1.4em;
78 | font-weight: normal;
79 | margin: 0;
80 | padding: 0;
81 | }
82 |
83 | div.sphinxsidebar h3 a {
84 | color: #8A0808;
85 | }
86 |
87 | div.sphinxsidebar h4 {
88 | font-family: 'Trebuchet MS', sans-serif;
89 | color: #8A0808;
90 | font-size: 1.3em;
91 | font-weight: normal;
92 | margin: 5px 0 0 0;
93 | padding: 0;
94 | }
95 |
96 | div.sphinxsidebar p {
97 | color: #8A0808;
98 | }
99 |
100 | div.sphinxsidebar p.topless {
101 | margin: 5px 10px 10px 10px;
102 | }
103 |
104 | div.sphinxsidebar ul {
105 | margin: 10px;
106 | padding: 0;
107 | color: #8A0808;
108 | }
109 |
110 | div.sphinxsidebar a {
111 | color: #8A0808;
112 | }
113 |
114 | div.sphinxsidebar input {
115 | border: 1px solid #8A0808;
116 | font-family: sans-serif;
117 | font-size: 1em;
118 | }
119 |
120 |
121 | /* for collapsible sidebar */
122 | div#sidebarbutton {
123 | background-color: #f2f2f2;
124 | }
125 |
126 |
127 | /* -- hyperlink styles ------------------------------------------------------ */
128 |
129 | a {
130 | color: #8A0808;
131 | text-decoration: none;
132 | }
133 |
134 | a:visited {
135 | color: #8A0808;
136 | text-decoration: none;
137 | }
138 |
139 | a:hover {
140 | text-decoration: underline;
141 | }
142 |
143 |
144 |
145 | /* -- body styles ----------------------------------------------------------- */
146 |
147 | div.body h1,
148 | div.body h2,
149 | div.body h3,
150 | div.body h4,
151 | div.body h5,
152 | div.body h6 {
153 | font-family: 'Trebuchet MS', sans-serif;
154 | background-color: #f2f2f2;
155 | font-weight: normal;
156 | color: #8A0808;
157 | border-bottom: 1px solid #ccc;
158 | margin: 20px -20px 10px -20px;
159 | padding: 3px 0 3px 10px;
160 | }
161 |
162 | div.body h1 { margin-top: 0; font-size: 200%; }
163 | div.body h2 { font-size: 160%; }
164 | div.body h3 { font-size: 140%; }
165 | div.body h4 { font-size: 120%; }
166 | div.body h5 { font-size: 110%; }
167 | div.body h6 { font-size: 100%; }
168 |
169 | a.headerlink {
170 | color: #8A0808;
171 | font-size: 0.8em;
172 | padding: 0 4px 0 4px;
173 | text-decoration: none;
174 | }
175 |
176 | a.headerlink:hover {
177 | background-color: #8A0808;
178 | color: white;
179 | }
180 |
181 | div.body p, div.body dd, div.body li {
182 | text-align: justify;
183 | line-height: 130%;
184 | }
185 |
186 | div.admonition p.admonition-title + p {
187 | display: inline;
188 | }
189 |
190 | div.admonition p {
191 | margin-bottom: 5px;
192 | }
193 |
194 | div.admonition pre {
195 | margin-bottom: 5px;
196 | }
197 |
198 | div.admonition ul, div.admonition ol {
199 | margin-bottom: 5px;
200 | }
201 |
202 | div.note {
203 | background-color: #eee;
204 | border: 1px solid #ccc;
205 | }
206 |
207 | div.seealso {
208 | background-color: #ffc;
209 | border: 1px solid #ff6;
210 | }
211 |
212 | div.topic {
213 | background-color: #eee;
214 | }
215 |
216 | div.warning {
217 | background-color: #ffe4e4;
218 | border: 1px solid #f66;
219 | }
220 |
221 | p.admonition-title {
222 | display: inline;
223 | }
224 |
225 | p.admonition-title:after {
226 | content: ":";
227 | }
228 |
229 | pre {
230 | padding: 5px;
231 | background-color: #f2f2f2;
232 | color: #333333;
233 | line-height: 120%;
234 | border: 1px solid #ac9;
235 | border-left: none;
236 | border-right: none;
237 | }
238 |
239 | tt {
240 | background-color: #ecf0f3;
241 | padding: 0 1px 0 1px;
242 | font-size: 0.95em;
243 | }
244 |
245 | th {
246 | background-color: #ede;
247 | }
248 |
249 | .warning tt {
250 | background: #efc2c2;
251 | }
252 |
253 | .note tt {
254 | background: #d6d6d6;
255 | }
256 |
257 | .viewcode-back {
258 | font-family: sans-serif;
259 | }
260 |
261 | div.viewcode-block:target {
262 | background-color: #f4debf;
263 | border-top: 1px solid #ac9;
264 | border-bottom: 1px solid #ac9;
265 | }
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/down-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/down-pressed.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/down.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/file.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/minus.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/sphinx-cbc/_static/plus.png
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #f0f0f0; }
3 | .highlight .c { color: #60a0b0; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
8 | .highlight .cp { color: #007020 } /* Comment.Preproc */
9 | .highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
10 | .highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
11 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
12 | .highlight .ge { font-style: italic } /* Generic.Emph */
13 | .highlight .gr { color: #FF0000 } /* Generic.Error */
14 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
15 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
16 | .highlight .go { color: #888888 } /* Generic.Output */
17 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
18 | .highlight .gs { font-weight: bold } /* Generic.Strong */
19 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
20 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
21 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
22 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
23 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
24 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
25 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
26 | .highlight .kt { color: #902000 } /* Keyword.Type */
27 | .highlight .m { color: #40a070 } /* Literal.Number */
28 | .highlight .s { color: #4070a0 } /* Literal.String */
29 | .highlight .na { color: #4070a0 } /* Name.Attribute */
30 | .highlight .nb { color: #007020 } /* Name.Builtin */
31 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
32 | .highlight .no { color: #60add5 } /* Name.Constant */
33 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
34 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
35 | .highlight .ne { color: #007020 } /* Name.Exception */
36 | .highlight .nf { color: #06287e } /* Name.Function */
37 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
38 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
39 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
40 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
41 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
42 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
43 | .highlight .mb { color: #40a070 } /* Literal.Number.Bin */
44 | .highlight .mf { color: #40a070 } /* Literal.Number.Float */
45 | .highlight .mh { color: #40a070 } /* Literal.Number.Hex */
46 | .highlight .mi { color: #40a070 } /* Literal.Number.Integer */
47 | .highlight .mo { color: #40a070 } /* Literal.Number.Oct */
48 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
49 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
50 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
51 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
52 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
53 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
54 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
55 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
56 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
57 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
58 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
59 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
60 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
61 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
62 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
63 | .highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/doc/pub/sphinx-cbc/_static/sidebar.js:
--------------------------------------------------------------------------------
1 | /*
2 | * sidebar.js
3 | * ~~~~~~~~~~
4 | *
5 | * This script makes the Sphinx sidebar collapsible.
6 | *
7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds
8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
9 | * used to collapse and expand the sidebar.
10 | *
11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
12 | * and the width of the sidebar and the margin-left of the document
13 | * are decreased. When the sidebar is expanded the opposite happens.
14 | * This script saves a per-browser/per-session cookie used to
15 | * remember the position of the sidebar among the pages.
16 | * Once the browser is closed the cookie is deleted and the position
17 | * reset to the default (expanded).
18 | *
19 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
20 | * :license: BSD, see LICENSE for details.
21 | *
22 | */
23 |
24 | $(function() {
25 | // global elements used by the functions.
26 | // the 'sidebarbutton' element is defined as global after its
27 | // creation, in the add_sidebar_button function
28 | var bodywrapper = $('.bodywrapper');
29 | var sidebar = $('.sphinxsidebar');
30 | var sidebarwrapper = $('.sphinxsidebarwrapper');
31 |
32 | // for some reason, the document has no sidebar; do not run into errors
33 | if (!sidebar.length) return;
34 |
35 | // original margin-left of the bodywrapper and width of the sidebar
36 | // with the sidebar expanded
37 | var bw_margin_expanded = bodywrapper.css('margin-left');
38 | var ssb_width_expanded = sidebar.width();
39 |
40 | // margin-left of the bodywrapper and width of the sidebar
41 | // with the sidebar collapsed
42 | var bw_margin_collapsed = '.8em';
43 | var ssb_width_collapsed = '.8em';
44 |
45 | // colors used by the current theme
46 | var dark_color = $('.related').css('background-color');
47 | var light_color = $('.document').css('background-color');
48 |
49 | function sidebar_is_collapsed() {
50 | return sidebarwrapper.is(':not(:visible)');
51 | }
52 |
53 | function toggle_sidebar() {
54 | if (sidebar_is_collapsed())
55 | expand_sidebar();
56 | else
57 | collapse_sidebar();
58 | }
59 |
60 | function collapse_sidebar() {
61 | sidebarwrapper.hide();
62 | sidebar.css('width', ssb_width_collapsed);
63 | bodywrapper.css('margin-left', bw_margin_collapsed);
64 | sidebarbutton.css({
65 | 'margin-left': '0',
66 | 'height': bodywrapper.height()
67 | });
68 | sidebarbutton.find('span').text('»');
69 | sidebarbutton.attr('title', _('Expand sidebar'));
70 | document.cookie = 'sidebar=collapsed';
71 | }
72 |
73 | function expand_sidebar() {
74 | bodywrapper.css('margin-left', bw_margin_expanded);
75 | sidebar.css('width', ssb_width_expanded);
76 | sidebarwrapper.show();
77 | sidebarbutton.css({
78 | 'margin-left': ssb_width_expanded-12,
79 | 'height': bodywrapper.height()
80 | });
81 | sidebarbutton.find('span').text('«');
82 | sidebarbutton.attr('title', _('Collapse sidebar'));
83 | document.cookie = 'sidebar=expanded';
84 | }
85 |
86 | function add_sidebar_button() {
87 | sidebarwrapper.css({
88 | 'float': 'left',
89 | 'margin-right': '0',
90 | 'width': ssb_width_expanded - 28
91 | });
92 | // create the button
93 | sidebar.append(
94 | ''
95 | );
96 | var sidebarbutton = $('#sidebarbutton');
97 | light_color = sidebarbutton.css('background-color');
98 | // find the height of the viewport to center the '<<' in the page
99 | var viewport_height;
100 | if (window.innerHeight)
101 | viewport_height = window.innerHeight;
102 | else
103 | viewport_height = $(window).height();
104 | sidebarbutton.find('span').css({
105 | 'display': 'block',
106 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2
107 | });
108 |
109 | sidebarbutton.click(toggle_sidebar);
110 | sidebarbutton.attr('title', _('Collapse sidebar'));
111 | sidebarbutton.css({
112 | 'color': '#FFFFFF',
113 | 'border-left': '1px solid ' + dark_color,
114 | 'font-size': '1.2em',
115 | 'cursor': 'pointer',
116 | 'height': bodywrapper.height(),
117 | 'padding-top': '1px',
118 | 'margin-left': ssb_width_expanded - 12
119 | });
120 |
121 | sidebarbutton.hover(
122 | function () {
123 | $(this).css('background-color', dark_color);
124 | },
125 | function () {
126 | $(this).css('background-color', light_color);
127 | }
128 | );
129 | }
130 |
131 | function set_position_from_cookie() {
132 | if (!document.cookie)
133 | return;
134 | var items = document.cookie.split(';');
135 | for(var k=0; k
4 |
5 |
6 |
7 |
8 |
9 |
10 | Search
11 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
45 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
Search
82 |
83 |
84 |
85 | Please activate JavaScript to enable the search
86 | functionality.
87 |
88 |
89 |
90 | From here you can search these documents. Enter your search
91 | words into the box below and click "search". Note that the search
92 | function will automatically search for all of the words. Pages
93 | containing fewer words won't appear in the result list.
94 |
95 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
117 |
118 |
119 |
128 |
129 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/doc/pub/web4sa.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/pub/web4sa.pdf
--------------------------------------------------------------------------------
/doc/src/web4sa/clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | name=web4sa
3 | doconce clean
4 | rm -rf ${name}_*.html sphinx-* automake_sphinx.py
5 | rm -rf src-${name}/apps/vib/vib1_flask/static/*.png
6 | rm -rf src-${name}/apps/vib/vib3_flask/static
7 | rm -rf src-${name}/apps/vib/vib1_django/static
8 | rm -rf src-${name}/apps/vib/vib2_django/static
9 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/Taylor_approx/compute.py:
--------------------------------------------------------------------------------
1 |
2 | def formula2series2pyfunc(formula, N, x, x0=0):
3 | """
4 | Convert a sympy expression formula in some independent
5 | variable x to a series representation of degree N terms
6 | and create a Python function for evaluating this series
7 | representation. Return Python functions for the formula
8 | and the series expansion, plus a LaTeX formula for the
9 | series expansion.
10 | """
11 | import sympy as sp
12 | series = formula.series(x, x0, N+1).removeO()
13 | series_pyfunc = sp.lambdify([x], series, modules='numpy')
14 | formula_pyfunc = sp.lambdify([x], formula, modules='numpy')
15 | # Return latex code with O() term since it starts with the lowest
16 | # order term and therefore looks better
17 | return formula_pyfunc, series_pyfunc, sp.latex(formula.series(x, x0, N+1))
18 |
19 | legends = [] # Store previous legends if not erase
20 |
21 | def visualize_series(
22 | formula, # string: formula
23 | independent_variable, # string: name of independent variable
24 | N, # int: degree of polynomial approximation
25 | xmin, xmax, ymin, ymax, # strings: extent of axes
26 | legend_loc, # string: upper left, etc.
27 | x0='0', # string: point of expansion
28 | erase='yes', # string: 'yes' or 'no'
29 | ):
30 | # Turn independent variable into sympy symbol, stored in x
31 | import sympy as sp
32 | exec('x = %s = sp.symbols("%s")' %
33 | (independent_variable, independent_variable))
34 | # Turn string formula into sympy expression. Need to
35 | # evaluate formula in the sympy namespace plus the
36 | # independent variable.
37 | namespace = sp.__dict__.copy()
38 | local = {}
39 | local[independent_variable] = x
40 | namespace.update(local)
41 | formula = eval(formula, namespace)
42 | # Turn x0 into sympy expression
43 | x0 = eval(x0, sp.__dict__)
44 | f, s, latex = formula2series2pyfunc(formula, N=N, x=x)
45 | # Make plot
46 | import numpy as np
47 | # Assume xmin, xmax, ymin, ymax are all strings and
48 | # allow symbols like pi
49 | xmin = eval(xmin, np.__dict__)
50 | xmax = eval(xmax, np.__dict__)
51 | ymin = eval(ymin, np.__dict__)
52 | ymax = eval(ymax, np.__dict__)
53 | x = np.linspace(xmin, xmax, 1001)
54 | import matplotlib.pyplot as plt
55 | global legends
56 | if erase == 'yes': # Start new figure?
57 | plt.figure()
58 | legends = []
59 | if not legends:
60 | # We come here every time the figure is empty so
61 | # we need to draw the formula
62 | legends.append('$%s$' % sp.latex(formula))
63 | plt.plot(x, f(x))
64 | plt.plot(x, s(x))
65 | plt.xlabel(independent_variable)
66 | plt.axis([xmin, xmax, ymin, ymax])
67 | legends.append('series, N=%d' % N)
68 | plt.legend(legends, loc=legend_loc)
69 | from StringIO import StringIO
70 | figfile = StringIO()
71 | plt.savefig(figfile, format='png')
72 | figfile.seek(0) # rewind to beginning of file
73 | import base64
74 | figdata_png = base64.b64encode(figfile.buf)
75 | return figdata_png, latex
76 |
77 | if __name__ == '__main__':
78 | visualize_series(
79 | 'sin(t)', 't', N=12,
80 | xmin='0', xmax='2*pi', ymin='-2', ymax='2',
81 | x0='0')
82 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/Taylor_approx/controller.py:
--------------------------------------------------------------------------------
1 | from model import InputForm
2 | from flask import Flask, render_template, request
3 | from compute import visualize_series as compute
4 |
5 | app = Flask(__name__)
6 |
7 | @app.route('/Taylor', methods=['GET', 'POST'])
8 | def index():
9 | form = InputForm(request.form)
10 | if request.method == 'POST' and form.validate():
11 | result = compute(formula=form.Formula.data,
12 | independent_variable=form.Variable.data,
13 | N=form.N.data,
14 | xmin=form.xmin.data,
15 | xmax=form.xmax.data,
16 | ymin=form.ymin.data,
17 | ymax=form.ymax.data,
18 | legend_loc=form.legend_loc.data,
19 | x0=form.x0.data,
20 | erase=form.Erase.data)
21 | else:
22 | result = None
23 | print request.method, [field.errors for field in form]
24 |
25 | return render_template('view.html', form=form, result=result)
26 |
27 | if __name__ == '__main__':
28 | app.run(debug=True)
29 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/Taylor_approx/model.py:
--------------------------------------------------------------------------------
1 | from wtforms import Form, TextField, SelectField, IntegerField, validators
2 | from math import pi
3 |
4 | class InputForm(Form):
5 | Variable = TextField(
6 | label='Name of independent variable',
7 | default='x',
8 | validators=[validators.InputRequired()])
9 | Formula = TextField(
10 | label='Expression in independent variable',
11 | default='sin(x)',
12 | validators=[validators.InputRequired()])
13 | xmin = TextField(
14 | label='Minimum x value in the plot', default='0',
15 | validators=[validators.InputRequired()])
16 | xmax = TextField(
17 | label='Maximum x value in the plot', default='2*pi',
18 | validators=[validators.InputRequired()])
19 | ymin = TextField(
20 | label='Minimum y value in the plot', default='-2',
21 | validators=[validators.InputRequired()])
22 | ymax = TextField(
23 | label='Maximum y value in the plot', default='2',
24 | validators=[validators.InputRequired()])
25 | x0 = TextField(
26 | label='Point for series expansion', default='0',
27 | validators=[validators.InputRequired()])
28 | N = IntegerField(
29 | label='Polynomial degree of series approximation', default=7,
30 | validators=[validators.InputRequired()])
31 | legend_loc = TextField(
32 | label='Location of legend in the plot', default='lower left',
33 | validators=[validators.InputRequired()])
34 | Erase = SelectField(
35 | label='Erase all curves?',
36 | # choices is (value, label) pairs: label gets printed
37 | # value is form.Erase.data
38 | choices=[('yes', 'Yes'), ('no', 'No')], default=2)
39 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/Taylor_approx/templates/view.html:
--------------------------------------------------------------------------------
1 |
9 |
12 |
13 |
14 |
15 |
36 |
37 |
38 | {% if result != None %}
39 |
40 |
41 |
42 |
43 |
44 |
45 | Series expansion of the formula:
46 | $$ {{ result[1] }} $$
47 |
48 |
49 |
50 | {% endif %}
51 |
52 |
53 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/addmul/compute.py:
--------------------------------------------------------------------------------
1 | def add(a, b):
2 | return a + b
3 |
4 | def mul(p, q):
5 | return p*q
6 |
7 | if __name__ == '__main__':
8 | print add(1, 2), mul(3, 4)
9 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/addmul/controller.py:
--------------------------------------------------------------------------------
1 | from model import AddForm, MulForm
2 | from flask import Flask, render_template, request
3 | from compute import add, mul
4 |
5 | app = Flask(__name__)
6 |
7 | @app.route('/addmul', methods=['GET', 'POST'])
8 | def index():
9 | form = {}
10 | result = {}
11 |
12 | # Try to make as common code as possible for the two apps
13 | name = 'add'
14 | f = form[name] = AddForm(request.form)
15 | if request.method == 'POST' and f.validate() and \
16 | request.form['btn'] == 'Add':
17 | result[name] = add(f.a.data, f.b.data)
18 | else:
19 | result[name] = None
20 |
21 | name = 'mul'
22 | f = form[name] = MulForm(request.form)
23 | if request.method == 'POST' and f.validate() and \
24 | request.form['btn'] == 'Multiply':
25 | result[name] = mul(f.p.data, f.q.data)
26 | else:
27 | result[name] = None
28 |
29 | return render_template('view.html',
30 | form=form, result=result)
31 |
32 | if __name__ == '__main__':
33 | app.run(debug=True)
34 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/addmul/model.py:
--------------------------------------------------------------------------------
1 | from wtforms import Form, FloatField
2 |
3 | class AddForm(Form):
4 | a = FloatField(label='', default=1.0)
5 | b = FloatField(label='', default=1.0)
6 |
7 | class MulForm(Form):
8 | p = FloatField(label='', default=2)
9 | q = FloatField(label='', default=2)
10 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace, zeros_like
2 | import matplotlib.pyplot as plt
3 | import os, time, glob, math
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute_vib(A=1, b=0.2, w=2*math.pi, T=5, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | t = linspace(0, T, resolution+1)
11 | y = damped_vibrations(t, A, b, w)
12 | plt.figure() # needed to avoid adding curves in plot
13 | plt.plot(t, y)
14 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
15 | if not os.path.isdir('static'):
16 | os.mkdir('static')
17 | else:
18 | # Remove old plot files
19 | for filename in glob.glob(os.path.join('static', '*.png')):
20 | os.remove(filename)
21 | # Use time since Jan 1, 1970 in filename in order make
22 | # a unique filename that the browser has not chached
23 | plotfile = os.path.join('static', str(time.time()) + '.png')
24 | plt.savefig(plotfile)
25 | return plotfile
26 |
27 | def gamma_density(x, a, h, A):
28 | # http://en.wikipedia.org/wiki/Gamma_distribution
29 | xA = x/float(A)
30 | return abs(h)/(math.gamma(a)*A)*(xA)**(a*h-1)*exp(-xA**h)
31 |
32 | def gamma_cumulative(x, a, h, A):
33 | # Integrate gamma_density using the Trapezoidal rule.
34 | # Assume x is array.
35 | g = gamma_density(x, a, h, A)
36 | r = zeros_like(x)
37 | for i in range(len(r)-1):
38 | r[i+1] = r[i] + 0.5*(g[i] + g[i+1])*(x[i+1] - x[i])
39 | return r
40 |
41 | def compute_gamma(a=0.5, h=2.0, A=math.sqrt(2), resolution=500,
42 | range=[0,7]):
43 | """Return plot and mean/st.dev. value of the gamma density."""
44 | print 'range:', type(range), range
45 | gah = math.gamma(a + 1./h)
46 | mean = A*gah/math.gamma(a)
47 | stdev = A/math.gamma(a)*math.sqrt(
48 | math.gamma(a + 2./h)*math.gamma(a) - gah**2)
49 | x = linspace(0, range[1]*stdev, resolution+1)
50 | y = gamma_density(x, a, h, A)
51 | plt.figure() # needed to avoid adding curves in plot
52 | plt.plot(x, y)
53 | plt.title('a=%g, h=%g, A=%g' % (a, h, A))
54 | if not os.path.isdir('static'):
55 | os.mkdir('static')
56 | else:
57 | # Remove old plot files
58 | for filename in glob.glob(os.path.join('static', '*.png')):
59 | os.remove(filename)
60 | # Use time since Jan 1, 1970 in filename in order make
61 | # a unique filename that the browser has not chached
62 | t = str(time.time())
63 | plotfile1 = os.path.join('static', 'density_%s.png' % t)
64 | plotfile2 = os.path.join('static', 'cumulative_%s.png' % t)
65 | plt.savefig(plotfile1)
66 | y = gamma_cumulative(x, a, h, A)
67 | plt.figure()
68 | plt.plot(x, y)
69 | plt.grid(True)
70 | plt.savefig(plotfile2)
71 | return plotfile1, plotfile2, mean, stdev
72 |
73 | if __name__ == '__main__':
74 | print compute_vib()
75 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/controller.py:
--------------------------------------------------------------------------------
1 | from view import app
2 |
3 | if __name__ == '__main__':
4 | app.run(debug=True)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/model.py:
--------------------------------------------------------------------------------
1 | """
2 | Example on generic model.py file which inspects the arguments
3 | of the compute function and automatically generates a relevant
4 | InputForm class.
5 | """
6 |
7 | import wtforms
8 | from math import pi
9 | from compute import compute_gamma as compute
10 | import numpy as np
11 | import inspect
12 | arg_names = inspect.getargspec(compute).args
13 | defaults = inspect.getargspec(compute).defaults
14 |
15 | class InputForm(wtforms.Form):
16 | pass
17 |
18 | # Augment defaults with None elements for the positional
19 | # arguments
20 | defaults = [None]*(len(arg_names)-len(defaults)) + list(defaults)
21 | # Map type of default to right form field
22 | type2form = {type(1.0): wtforms.FloatField,
23 | type(1): wtforms.IntegerField,
24 | type(''): wtforms.TextField,
25 | type([]): wtforms.TextField,
26 | type(()): wtforms.TextField,
27 | type(np.array([1,2.])): wtforms.TextField,
28 | }
29 |
30 | def get_type_as_str(obj):
31 | return str(type(obj)).split("'")[1]
32 |
33 | for name, value in zip(arg_names, defaults):
34 | if value is None:
35 | setattr(InputForm, name, wtforms.FloatField(
36 | validators=[wtforms.validators.InputRequired()]))
37 | else:
38 | if type(value) in type2form:
39 | setattr(InputForm, name, type2form[type(value)](
40 | default=value,
41 | label='(%s)' % get_type_as_str(value),
42 | validators=[wtforms.validators.InputRequired()]))
43 | else:
44 | raise TypeError('argument %s %s not supported' %
45 | name, type(value))
46 |
47 | if __name__ == '__main__':
48 | for item in dir(InputForm):
49 | if item in arg_names:
50 | print item, getattr(InputForm, item)
51 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/templates/view.html:
--------------------------------------------------------------------------------
1 |
15 |
16 | {% if result != None %}
17 | {{ result|safe }}
18 | {% endif %}
19 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/templates/view_results.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Mean value: {{ result[2] }}
9 | Standard deviation value: {{ result[3] }}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/templates/view_results_default.py:
--------------------------------------------------------------------------------
1 |
2 | {% if result != None %}
3 | {% if type(result) == type("") and
4 | result[:-4] == '.png' or result[:-4] == '.gif' or
5 | result[:-4] == '.jpg' %}
6 |
7 | {% else %}
8 | {{ str(result) }}
9 | {% endif %}
10 | {% endif %}
11 |
12 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/gen_ext/view.py:
--------------------------------------------------------------------------------
1 | from model import InputForm
2 | from flask import Flask, render_template, request
3 | from compute import compute_gamma as compute
4 | import sys, os, inspect
5 |
6 | app = Flask(__name__)
7 |
8 | @app.route('/vib3_ext', methods=['GET', 'POST'])
9 | def index():
10 | form = InputForm(request.form)
11 | if request.method == 'POST' and form.validate():
12 | arg_names = inspect.getargspec(compute).args
13 | kwargs = {name: getattr(form, name).data
14 | for name in arg_names if hasattr(form, name)}
15 | # Run eval on the text
16 | # Note that form.name.label is (list)
17 | for name in kwargs:
18 | if hasattr(form, name) and \
19 | hasattr(getattr(form, name), 'label'):
20 | label = str(getattr(form, name).label)
21 | for tp in ('(list)', '(tuple)', '(nd.array)'):
22 | if tp in label:
23 | kwargs[name] = eval(kwargs[name])
24 |
25 | result = compute(**kwargs)
26 | else:
27 | result = None
28 | if result:
29 | # result must be transformed to HTML and inserted as a
30 | # string in the generic view.html file
31 | result = render_template('view_results.html', result=result)
32 | return render_template('view.html', form=form, result=result)
33 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/plot_formula/README.txt:
--------------------------------------------------------------------------------
1 | 1. Make the compute function.
2 | 2. Copy model.py and controller.py from vib1.
3 | 3. Edit *.py.
4 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/plot_formula/compute.py:
--------------------------------------------------------------------------------
1 | def plot_formula(formula, domain, erase):
2 | """
3 | formula: string containing function expression of x to be plotted.
4 | domain: 2-list of min and mix x value in the plot.
5 | Return PNG plot as a string.
6 | """
7 | # Evaluate domain is list and extract xmin and xmax.
8 | # Evaluate in numpy namespace so that '[0, pi/2]' is a
9 | # possible domain specification.
10 | import numpy as np
11 | input_error = False
12 | try:
13 | domain_list = eval(domain, np.__dict__)
14 | except Exception as e:
15 | input_error = True
16 | if not isinstance(domain, list) and len(domain) == 2:
17 | input_error = True
18 | if input_error:
19 | raise ValueError('Specified domain "%s" is not a 2-list' % domain)
20 | xmin, xmax = domain_list
21 |
22 | # Define x coordinates
23 | x = np.linspace(xmin, xmax, 10001)
24 | # Turn formula into numpy expression.
25 | # Need np.__dict__ namespace and the x defined here
26 | namespace = np.__dict__.copy()
27 | namespace.update({'x': x})
28 | try:
29 | y = eval(formula, namespace)
30 | except Exception as e:
31 | raise ValueError(
32 | 'expression "%s" could not be evaluated:\n%s' %
33 | formula, str(e))
34 |
35 | # Make plot
36 | import matplotlib.pyplot as plt
37 | if erase == 'yes':
38 | plt.figure()
39 | plt.plot(x, y)
40 | plt.xlabel('x')
41 | from StringIO import StringIO
42 | figfile = StringIO()
43 | plt.savefig(figfile, format='png')
44 | figfile.seek(0) # rewind to beginning of file
45 | import base64
46 | figdata_png = base64.b64encode(figfile.buf)
47 | return figdata_png
48 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/plot_formula/controller.py:
--------------------------------------------------------------------------------
1 | from model import InputForm
2 | from flask import Flask, render_template, request
3 | from compute import plot_formula as compute
4 |
5 | app = Flask(__name__)
6 |
7 | @app.route('/formula', methods=['GET', 'POST'])
8 | def index():
9 | form = InputForm(request.form)
10 | if request.method == 'POST' and form.validate():
11 | result = compute(form.Formula.data, form.Domain.data,
12 | form.Erase.data)
13 | else:
14 | result = None
15 |
16 | return render_template('view.html', form=form, result=result)
17 |
18 | if __name__ == '__main__':
19 | app.run(debug=True)
20 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/plot_formula/model.py:
--------------------------------------------------------------------------------
1 | from wtforms import Form, TextField, SelectField, validators
2 | from math import pi
3 |
4 | class InputForm(Form):
5 | Formula = TextField(
6 | label='Expression in x',
7 | default='sin(x)',
8 | validators=[validators.InputRequired()])
9 | Domain = TextField(
10 | label='Domain: [xmin, xmax]', default='[0, 2*pi]',
11 | validators=[validators.InputRequired()])
12 | Erase = SelectField(
13 | label='Erase all curves?',
14 | # choices is (value, label) pairs: label gets printed
15 | # value is form.Erase.data
16 | choices=[('yes', 'Yes'), ('no', 'No')], default=2)
17 |
--------------------------------------------------------------------------------
/doc/src/web4sa/exer/plot_formula/templates/view.html:
--------------------------------------------------------------------------------
1 |
22 |
23 | {% if result != None %}
24 |
25 |
26 |
27 | {% endif %}
28 |
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/Taylor_approx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/Taylor_approx.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/Taylor_approx_exp2t.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/Taylor_approx_exp2t.pdf
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/Taylor_approx_exp2t.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/Taylor_approx_exp2t.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/gen_flask_gamma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/gen_flask_gamma.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw1_django_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw1_django_input.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw1_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw1_django_output.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw1_flask_input.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw1_flask_output.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw2_django_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw2_django_output.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/hw2_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/hw2_flask_output.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/login_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/login_main.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/login_register.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/login_register.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/plot_formula.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/plot_formula.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/upload1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/upload1.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/upload2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/upload2.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/upload3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/upload3.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_bootstrap.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_bootswatch_journal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_bootswatch_journal.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_error1.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_input.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_latex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_latex.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_output.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib1_flask_table2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib1_flask_table2.png
--------------------------------------------------------------------------------
/doc/src/web4sa/fig-web4sa/vib2_flask_error1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/fig-web4sa/vib2_flask_error1.png
--------------------------------------------------------------------------------
/doc/src/web4sa/html_templates/template_django.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 | %(title)s
20 |
21 |
22 |
34 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 | %(main)s
49 |
50 |
51 |
52 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/doc/src/web4sa/html_templates/template_flask.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 | %(title)s
20 |
21 |
22 |
34 |
35 |
36 |
37 |
44 |
45 |
46 |
47 | %(main)s
48 |
49 |
50 |
51 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/doc/src/web4sa/html_templates/template_flask_django.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 | %(title)s
20 |
21 |
22 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 | %(main)s
49 |
50 |
51 |
52 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/doc/src/web4sa/index.do.txt:
--------------------------------------------------------------------------------
1 | TITLE: Using Web Frameworks for Scientific Applications
2 | AUTHOR: Hans Petter Langtangen at Center for Biomedical Computing, Simula Research Laboratory and Department of Informatics, University of Oslo
3 | AUTHOR: Anders Johansen at Center for Biomedical Computing, Simula Research Laboratory
4 | DATE: today
5 |
6 | <%
7 | name = 'web4sa'
8 |
9 | import glob
10 | sphinx_styles = ', '.join(['"%s style": "%s/index.html"' % (n[7:], n)
11 | for n in glob.glob('sphinx-*')
12 | if n != 'sphinx-rootdir'])
13 | %>
14 |
15 | #======= Tutorials on web frameworks for scientific applications =======
16 |
17 | * "Flask tutorial in HTML": "${name}_flask.html"
18 | * "Django tutorial in HTML": "${name}_django.html"
19 | * "Flask and Django tutorial in HTML": "${name}_solarized.html"
20 | * "Flask and Django tutorial in one big HTML file": "${name}_plain_all.html"
21 | * "Flask and Django tutorial in Sphinx": "sphinx-cbc/index.html"
22 | * "Flask and Django tutorial in LaTeX/PDF": "${name}.pdf"
23 |
--------------------------------------------------------------------------------
/doc/src/web4sa/links.do.txt:
--------------------------------------------------------------------------------
1 | # #if TOPIC == 'Flask+Django'
2 | ======= Resources =======
3 | # #else
4 | ======= ${TOPIC} resources =======
5 | # #endif
6 |
7 | # #if TOPIC in ('Flask+Django', 'Flask')
8 |
9 | # #if TOPIC == 'Flask+Django'
10 | ===== Flask resources =====
11 | # #endif
12 |
13 | * "Flask website": "http://flask.pocoo.org/"
14 | * "Flask Quick Start": "http://flask.pocoo.org/docs/0.10/tutorial/"
15 | * "Flask tutorial": "http://flask.pocoo.org/docs/0.10/tutorial/"
16 | * "The Flask Mega-Tutorial": "http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world" by M. Grinberg
17 | * "WTForms Documentation": "http://wtforms.simplecodes.com/docs/0.6/index.html"
18 | * "The Jinja2 templating language": "http://jinja.pocoo.org/docs/"
19 | * "The Werkzeug library": "http://werkzeug.pocoo.org/"
20 | * "An Introduction to Python's Flask Framework": "http://code.tutsplus.com/tutorials/an-introduction-to-pythons-flask-framework--net-28822" by L. Polepeddi
21 | * "Discover Flask, Part I - Setting up a Static Site": "https://realpython.com/blog/python/introduction-to-flask-part-1-setting-up-a-static-site/"
22 | * Flaskr: A Minimal Blog Application: "Code": "https://github.com/mitsuhiko/flask/tree/master/examples/flaskr/", "Explanation": "https://stormpath.com/blog/build-a-flask-app-in-30-minutes/"
23 | * "Flask Login with Facebook, Twitter, and OpenID": "http://peterhudec.github.io/authomatic/examples/flask-simple.html"
24 | * "Lightweight Python Apps with Flask, Bootstrap, and Heroku": "http://blog.shea.io/lightweight-python-apps-with-flask-twitter-bootstrap-and-heroku/" by R. Shea
25 | * "How to Structure Large Flask Applications": "https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications"
26 | * "Explore Flask": "https://exploreflask.com/index.html" by R. Picard (online book)
27 | * "Flask Mega Tutorial for Data Scientists": "http://www.datacommunitydc.org/blog/2014/02/flask-mega-meta-tutorial-data-scientists"
28 | * "Quick Flask++ tutorial": "http://maximebf.com/blog/2012/10/building-websites-in-python-with-flask/#.UxV4jHVdXn4"
29 | * "Flask-Bootstrap": "https://github.com/mbr/flask-bootstrap" with "documentation": "http://pythonhosted.org/Flask-Bootstrap/", "basic usage": "http://pythonhosted.org/Flask-Bootstrap/basic-usage.html" and "example": "https://github.com/mbr/flask-bootstrap/blob/master/sample_application/__init__.py"
30 | * "Skulpt: Interactive Python in the browser": "http://www.skulpt.org/" (but no support for `numpy`, `scipy`, or `matplotlib`)
31 |
32 | # #ifdef INTERESTING_BUT_NOT_RELEVANT
33 | * "A complete modern Python project with virtualenv, testing, setup.py, etc.": "https://github.com/splaice/py-bootstrap"
34 | * "Python for computer games": "http://inventwithpython.com/"
35 | * "Flask and Boostrap intro": "http://pythonthusiast.pythonblogs.com/230_pythonthusiast/archive/1309_building_in_openshift_part_iv__application_layout_and_templating_using_bootstrap_3_and_jinja_2.html" ("sample app": "http://bio-ekowibowo.rhcloud.com/" has sign in functionality and bootstrap layout explained "here": "http://pythonthusiast.pythonblogs.com/230_pythonthusiast/archive/1317_building_python_flask_application_in_openshiftheroku_replacement_part_vii__adding_sign_in_form_using_bootstrap_3_and_login_feature_using_flask-login.html")
36 | # #endif
37 | # #endif
38 |
39 | # #if TOPIC in ('Flask+Django', 'Django')
40 |
41 | # #if TOPIC == 'Flask+Django'
42 | ===== Django resources =====
43 | # #endif
44 |
45 | * "Django webpage": "https://www.djangoproject.com/"
46 | * "List of Web tutorials": "https://code.djangoproject.com/wiki/Tutorials"
47 | * "YouTube videos": "http://www.youtube.com/playlist?list=PL385A53B00B8B158E"
48 | * "Effective Django Tutorial": "http://www.effectivedjango.com/tutorial/"
49 | * "Django by Example": "http://lightbird.net/dbe2/" (blog, questionnaire, etc.)
50 | * "Django for Scientific Applications": "http://www.blopig.com/blog/2013/09/django-for-scientific-applications/"
51 | * "A Tutorial for Deploying a Django Application that Uses Numpy and Scipy to Google Compute Engine Using Apache2 and modwsgi": "http://www.datacommunitydc.org/blog/2013/12/a-tutorial-for-deploying-a-django-application-that-uses-numpy-and-scipy-to-google-compute-engine-using-apache2-and-modwsgi"
52 |
53 | # #endif
54 |
--------------------------------------------------------------------------------
/doc/src/web4sa/make.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Compile document in HTML versions, Flask+Django, Flask only,
3 | # Django only, Sphinx version, and LaTeX/PDF version.
4 | set -x
5 | sh clean.sh
6 |
7 | function system {
8 | "$@"
9 | if [ $? -ne 0 ]; then
10 | echo "make.sh: unsuccessful command $@"
11 | echo "abort!"
12 | exit 1
13 | fi
14 | }
15 |
16 | name=web4sa
17 |
18 | system doconce format html $name -DTOPIC=Flask+Django --html_style=bloodish
19 | cp $name.html ${name}_plain_all.html
20 | cp $name.html ${name}_plain.html
21 | system doconce split_html ${name}_plain --nav_button=text
22 |
23 | system doconce format html $name -DTOPIC=Flask+Django --html_style=solarized3
24 | cp $name.html ${name}_solarized.html
25 | system doconce split_html ${name}_solarized --nav_button=text
26 |
27 | system doconce format html ${name} -DTOPIC=Flask --html_style=bootstrap --html_template=html_templates/template_flask.html --html_output=${name}_flask
28 | system doconce split_html ${name}_flask
29 |
30 | system doconce format html ${name} -DTOPIC=Django --html_style=bootstrap --html_template=html_templates/template_django.html --html_output=${name}_django
31 | system doconce split_html ${name}_django
32 |
33 | system doconce format sphinx $name -DTOPIC=Flask+Django
34 | system doconce split_rst $name
35 | system doconce sphinx_dir $name theme=cbc
36 | system python automake_sphinx.py
37 | mv sphinx-rootdir/_build/html sphinx-cbc
38 | #cd sphinx-rootdir
39 | # Note: make_themes.sh does not fix headings with numbers (1), (2) etc
40 | # such as automake_sphinx.py does
41 | #sh make_themes.sh cbc basicstrap redcloud
42 | #cd ..
43 | #mv sphinx-rootdir/sphinx-* .
44 |
45 |
46 | system doconce format pdflatex $name -DTOPIC=Flask+Django
47 | system doconce ptex2tex $name envir=minted
48 | system pdflatex -shell-escape $name
49 | makeindex $name
50 | pdflatex -shell-escape $name
51 | pdflatex -shell-escape $name
52 |
53 | doconce format html index --html_style=bootstrap --html_boostrap_jumbotron=off --html_bootstrap_navbar=off
54 |
55 | # Publish
56 | dest=../../pub
57 | rm -rf $dest/sphinx-rootdir $dest/sphinx-*
58 | rm -rf sphinx-rootdir
59 | cp -r ${name}*.html .*${name}*.html $name.pdf sphinx-* $dest
60 | cp -r fig-$name/* $dest/fig-$name/
61 | cp index.html $dest
62 |
--------------------------------------------------------------------------------
/doc/src/web4sa/publish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | name=web4sa
3 | cp -r *.html .*.html html_templates sphinx-* $name.pdf fig-$name ../../pub/
4 | rm -rf ../../pub/sphinx-rootdir # remove this if it was copied
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/slides-web4sa/intro.do.txt:
--------------------------------------------------------------------------------
1 | !split
2 | ======= Web frameworks =======
3 |
4 | idx{web frameworks}
5 |
6 | Goal:
7 |
8 | o generate a web page with input data to your application,
9 | o run the application to perform mathematical computations, and
10 | o generate a web page with the results of the computations.
11 |
12 | Technologies:
13 |
14 | * CGI script
15 | * Web frameworks: Django, Flask, web2py, Bottle, ...
16 |
17 | Here:
18 |
19 | # #if TOPIC == 'Flask+Django'
20 | * Intro to "Flask": "http://flask.pocoo.org/" (first) and "Django": "https://www.djangoproject.com/"
21 | # #elif TOPIC == 'Flask'
22 | * Intro to "Flask": "http://flask.pocoo.org/"
23 | # #elif TOPIC == 'Django'
24 | * Intro to "Django": "https://www.djangoproject.com/"
25 | # #endif
26 | * Focus: how to use web frameworks for *scientific applications*
27 |
28 | !split
29 | ===== Required background knowledge =====
30 | # #if TOPIC == 'Flask+Django'
31 | * Python packages and modules, classes, decorators
32 | # #elif TOPIC == 'Flask'
33 | * Python modules, decorators
34 | # #elif TOPIC == 'Django'
35 | * Python packages and modules, classes
36 | # #endif
37 |
38 | <%
39 | github_path = 'https://github.com/hplgit/web4sciapps/tree/master/doc/src/web4sa'
40 | app_path = 'src-web4sa/apps/'
41 | %>
42 |
43 | !split
44 | ===== The code associated with these slides is on the web =====
45 |
46 | All the files associated with this document are available in a
47 | "GitHub repository": "https://github.com/hplgit/web4sciapps/".
48 | The relevant files for the web applications are located
49 | in a subtree "`doc/src/web4sa/src-web4sa/apps`": "${github_path}/${app_path}"
50 | of this repository.
51 |
52 | !split
53 | ===== The MVC pattern for organizing the software =====
54 |
55 | idx{MVC pattern}
56 |
57 | * MVC = Model-View-Controller
58 | * Goal: separate the user's interaction with an application from the inner
59 | workings of the application
60 | * Scientific application: separate the math from the user interface
61 | and visualization
62 | * See the "Wikipedia definition of the MVC pattern": "http://en.wikipedia.org/wiki/MVC_Pattern"
63 | * Different web frameworks interpret MCV differently...
64 |
65 | The classical MVC pattern introduces
66 |
67 | * the model to hold the data
68 | * the view to display the data
69 | * the controller to move the data by gluing the model and the view.
70 |
71 | We add for scientific applications
72 |
73 | * the *compute* component to perform mathematical computations
74 |
75 | !split
76 | ===== The MVC pattern for scientific applications =====
77 |
78 | * The model contains the data (often only the input data) of the application,
79 | * The view controls the user interface that handles input and output data,
80 | and also calls to functionality that computes the output given the input.
81 |
82 | Implementation:
83 | * Model: a Python class with static attributes holding the data
84 | * View: Python code processing the model's data, calling the
85 | compute component, and specifying HTML
86 | templates for the design of the web pages
87 | # #if TOPIC == 'Django'
88 | * Django has files with names `models.py` and `views.py` so the
89 | model and view concepts are very explicit
90 | The controller functionality in Django lies both in the `views.py` file and
91 | in configuration files (`settings.py` and `urls.py`). The view component consists of the `views.py` file and HTML templates
92 | # #elif TOPIC == 'Flask'
93 | * Flask does not force any MVC pattern on the programmer, but
94 | the code can easily be split into
95 | model, view, controller, and compute components
96 | # #elif TOPIC == 'Flask+Django'
97 | * Django has files with names `models.py` and `views.py` so the
98 | model and view concepts are very explicit
99 | The controller functionality in Django lies both in the `views.py` file and
100 | in configuration files (`settings.py` and `urls.py`). The view component consists of the `views.py` file and HTML templates
101 | * Flask does not force any MVC pattern on the programmer, but
102 | the code can easily be split into
103 | model, view, controller, and compute components
104 | # #endif
105 |
106 | Let's learn from examples!
107 |
108 | !split
109 | ===== A very simple application =====
110 |
111 | ## Define Mako variable for path to source code
112 | <%
113 | #src_path = '../../../src/apps/'
114 | src_path = 'src-web4sa/apps/'
115 | app_path = src_path + 'py_apps/hw_orig'
116 | %>
117 |
118 | * Start: ``scientific hello world program''
119 | * Read a number, write ``Hello, World!'', and the sine of the number
120 |
121 | Plain Python version:
122 |
123 | @@@CODE ${app_path}/hw.py
124 |
125 | Execution:
126 |
127 | !bc sys
128 | Terminal> python hw.py 1.2
129 | Hello, World! sin(1.2)=0.932039
130 | !ec
131 |
132 | Web version: read `r` from a web page, compute the sine,
133 | and write out a new web page
134 |
135 | !split
136 | ===== Application of the MVC pattern =====
137 | label{wf:hw:mvc}
138 |
139 | ## Define Mako variable for path to source code
140 | <%
141 | app_path = src_path + 'py_apps/hw_mvc'
142 | %>
143 |
144 | * Goal: *refactor* our program to fit the MVC pattern
145 | (with a compute component)
146 | * Method: create four modules: `model`, `view`,
147 | `compute`, and `controller`.
148 | * `compute` contains `compute(r)` that performs
149 | the mathematics and returns the value `s = sin(r)`
150 | * `model` holds the input data, here `r`
151 | * `view` contains `get_input` for reading input data
152 | and `present_output` for presenting the output
153 | (given input, it calls `compute` and
154 | generates the output)
155 | * `controller` calls the view to initialize
156 | the model's data from the command line and then calls the view
157 | to present the output
158 |
159 | !split
160 | ===== The model module contains the input data =====
161 |
162 | @@@CODE ${app_path}/model.py
163 |
164 | !split
165 | ===== The view module holds the communication with the user =====
166 |
167 | @@@CODE ${app_path}/view.py
168 |
169 | !split
170 | ===== The mathematics is encapsulated in the compute component =====
171 |
172 | @@@CODE ${app_path}/compute.py
173 |
174 | !split
175 | ===== The controler glues the model and the view =====
176 |
177 | @@@CODE ${app_path}/controller.py
178 |
179 | Let us try our refactored code:
180 |
181 | !bc sys
182 | Terminal> python controller.py 1.2
183 | Hello, World! sin(1.2)=0.932039
184 | !ec
185 |
186 | Next step: make a web interface
187 |
--------------------------------------------------------------------------------
/doc/src/web4sa/slides-web4sa/links.do.txt:
--------------------------------------------------------------------------------
1 | # #if TOPIC == 'Flask+Django'
2 | ======= Resources =======
3 | # #else
4 | ======= ${TOPIC} resources =======
5 | # #endif
6 |
7 | # #if TOPIC in ('Flask+Django', 'Flask')
8 |
9 | # #if TOPIC == 'Flask+Django'
10 | ===== Flask resources =====
11 | # #endif
12 |
13 | * "Flask website": "http://flask.pocoo.org/"
14 | * "Flask Quick Start": "http://flask.pocoo.org/docs/0.10/tutorial/"
15 | * "Flask tutorial": "http://flask.pocoo.org/docs/0.10/tutorial/"
16 | * "The Flask Mega-Tutorial": "http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world" by M. Grinberg
17 | * "WTForms Documentation": "http://wtforms.simplecodes.com/docs/0.6/index.html"
18 | * "The Jinja2 templating language": "http://jinja.pocoo.org/docs/"
19 | * "The Werkzeug library": "http://werkzeug.pocoo.org/"
20 | * "An Introduction to Python's Flask Framework": "http://code.tutsplus.com/tutorials/an-introduction-to-pythons-flask-framework--net-28822" by L. Polepeddi
21 | * "Discover Flask, Part I - Setting up a Static Site": "https://realpython.com/blog/python/introduction-to-flask-part-1-setting-up-a-static-site/"
22 | * Flaskr: A Minimal Blog Application: "Code": "https://github.com/mitsuhiko/flask/tree/master/examples/flaskr/", "Explanation": "https://stormpath.com/blog/build-a-flask-app-in-30-minutes/"
23 | * "Flask Login with Facebook, Twitter, and OpenID": "http://peterhudec.github.io/authomatic/examples/flask-simple.html"
24 | * "Lightweight Python Apps with Flask, Bootstrap, and Heroku": "http://blog.shea.io/lightweight-python-apps-with-flask-twitter-bootstrap-and-heroku/" by R. Shea
25 | * "How to Structure Large Flask Applications": "https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications"
26 | * "Explore Flask": "https://exploreflask.com/index.html" by R. Picard (online book)
27 | * "Flask Mega Tutorial for Data Scientists": "http://www.datacommunitydc.org/blog/2014/02/flask-mega-meta-tutorial-data-scientists"
28 |
29 | # #endif
30 |
31 | # #if TOPIC in ('Flask+Django', 'Django')
32 |
33 | # #if TOPIC == 'Flask+Django'
34 | ===== Django resources =====
35 | # #endif
36 |
37 | * "Django webpage": "https://www.djangoproject.com/"
38 | * "List of Web tutorials": "https://code.djangoproject.com/wiki/Tutorials"
39 | * "YouTube videos": "http://www.youtube.com/playlist?list=PL385A53B00B8B158E"
40 | * "Effective Django Tutorial": "http://www.effectivedjango.com/tutorial/"
41 | * "Django by Example": "http://lightbird.net/dbe2/" (blog, questionnaire, etc.)
42 | * "Django for Scientific Applications": "http://www.blopig.com/blog/2013/09/django-for-scientific-applications/"
43 | * "A Tutorial for Deploying a Django Application that Uses Numpy and Scipy to Google Compute Engine Using Apache2 and modwsgi": "http://www.datacommunitydc.org/blog/2013/12/a-tutorial-for-deploying-a-django-application-that-uses-numpy-and-scipy-to-google-compute-engine-using-apache2-and-modwsgi"
44 |
45 | # #endif
46 |
--------------------------------------------------------------------------------
/doc/src/web4sa/slides_web4sa.do.txt:
--------------------------------------------------------------------------------
1 | TITLE: Using Web Frameworks for Scientific Applications
2 | AUTHOR: Hans Petter Langtangen at Center for Biomedical Computing, Simula Research Laboratory & Department of Informatics, University of Oslo
3 | AUTHOR: Anders E. Johansen at Center for Biomedical Computing, Simula Research Laboratory
4 | DATE: today
5 |
6 | !split
7 | TOC: on
8 |
9 | # #include "slides-websa/intro.do.txt"
10 |
11 | # #if TOPIC in ('Flask+Django', 'Flask')
12 | # #include "slides-websa/flask_hw.do.txt"
13 | # #endif
14 |
15 | # #if TOPIC in ('Flask+Django', 'Django')
16 | # #include "slides-websa/django_hw.do.txt"
17 | # #endif
18 |
19 | # #if TOPIC in ('Flask+Django', 'Flask')
20 | # #include "slides-websa/flask_vib.do.txt"
21 | # #endif
22 |
23 | # #if TOPIC in ('Flask+Django', 'Django')
24 | # #include "slides-websa/django_vib.do.txt"
25 | # #endif
26 |
27 | # #include "slides-websa/links.do.txt"
28 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/__init__.py
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/compute.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def compute(r):
4 | return math.sin(r)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.forms import ModelForm
3 |
4 | class Input(models.Model):
5 | r = models.FloatField()
6 |
7 | class InputForm(ModelForm):
8 | class Meta:
9 | model = Input
10 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/templates/hw1.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/tests.py:
--------------------------------------------------------------------------------
1 | """
2 | This file demonstrates writing tests using the unittest module. These will pass
3 | when you run "manage.py test".
4 |
5 | Replace this with more appropriate tests for your application.
6 | """
7 |
8 | from django.test import TestCase
9 |
10 |
11 | class SimpleTest(TestCase):
12 | def test_basic_addition(self):
13 | """
14 | Tests that 1 + 1 always equals 2.
15 | """
16 | self.assertEqual(1 + 1, 2)
17 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw1/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from django.http import HttpResponse
4 | from models import InputForm
5 | from compute import compute
6 |
7 | def index(request):
8 | if request.method == 'POST':
9 | form = InputForm(request.POST)
10 | if form.is_valid():
11 | form = form.save(commit=False)
12 | return present_output(form)
13 | else:
14 | form = InputForm()
15 |
16 | return render_to_response('hw1.html',
17 | {'form': form}, context_instance=RequestContext(request))
18 |
19 | def present_output(form):
20 | r = form.r
21 | s = compute(r)
22 | return HttpResponse('Hello, World! sin(%s)=%s' % (r, s))
23 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/__init__.py
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/compute.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def compute(r):
4 | return math.sin(r)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.forms import ModelForm
3 |
4 | class Input(models.Model):
5 | r = models.FloatField()
6 |
7 | class InputForm(ModelForm):
8 | class Meta:
9 | model = Input
10 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/templates/hw2.html:
--------------------------------------------------------------------------------
1 |
8 |
9 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/hw2/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from django.http import HttpResponse
4 | from models import InputForm
5 | from compute import compute
6 |
7 | def index(request):
8 | s = None # initial value of result
9 | if request.method == 'POST':
10 | form = InputForm(request.POST)
11 | if form.is_valid():
12 | form = form.save(commit=False)
13 | r = form.r
14 | s = compute(r)
15 | else:
16 | form = InputForm()
17 |
18 | return render_to_response('hw2.html',
19 | {'form': form,
20 | 's': '%.5f' % s if isinstance(s, float) else ''
21 | }, context_instance=RequestContext(request))
22 |
23 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/__init__.py
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace
2 | import matplotlib.pyplot as plt
3 | import os, time, glob
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute(A, b, w, T, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | print os.getcwd()
11 | t = linspace(0, T, resolution+1)
12 | y = damped_vibrations(t, A, b, w)
13 | plt.figure() # needed to avoid adding curves in plot
14 | plt.plot(t, y)
15 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
16 | if not os.path.isdir('static'):
17 | os.mkdir('static')
18 | else:
19 | # Remove old plot files
20 | for filename in glob.glob(os.path.join('static', '*.png')):
21 | os.remove(filename)
22 | # Use time since Jan 1, 1970 in filename in order make
23 | # a unique filename that the browser has not chached
24 | plotfile = os.path.join('static', str(time.time()) + '.png')
25 | plt.savefig(plotfile)
26 | return plotfile
27 |
28 | if __name__ == '__main__':
29 | print compute(1, 0.1, 1, 20)
30 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.forms import ModelForm
3 | from math import pi
4 |
5 | class Input(models.Model):
6 | A = models.FloatField(
7 | verbose_name=' amplitude (m)', default=1.0)
8 | b = models.FloatField(
9 | verbose_name=' damping coefficient (kg/s)', default=0.0)
10 | w = models.FloatField(
11 | verbose_name=' frequency (1/s)', default=2*pi)
12 | T = models.FloatField(
13 | verbose_name=' time interval (s)', default=18)
14 |
15 | class InputForm(ModelForm):
16 | class Meta:
17 | model = Input
18 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/templates/vib1.html:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | {% if result != None %}
17 | {% load static %}
18 |
19 | {% endif %}
20 |
21 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib1/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from django.http import HttpResponse
4 | from models import InputForm
5 | from compute import compute
6 | import os
7 |
8 | def index(request):
9 | os.chdir(os.path.dirname(__file__))
10 | result = None
11 | if request.method == 'POST':
12 | form = InputForm(request.POST)
13 | if form.is_valid():
14 | form2 = form.save(commit=False)
15 | result = compute(form2.A, form2.b, form2.w, form2.T)
16 | result = result.replace('static/', '')
17 | else:
18 | form = InputForm()
19 |
20 | return render_to_response('vib1.html',
21 | {'form': form,
22 | 'result': result,
23 | }, context_instance=RequestContext(request))
24 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hplgit/web4sciapps/8d225ced1928e0706c43044429325c8ff9b01e76/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/__init__.py
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace
2 | import matplotlib.pyplot as plt
3 | import os, time, glob
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute(A, b, w, T, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | print os.getcwd()
11 | t = linspace(0, T, resolution+1)
12 | y = damped_vibrations(t, A, b, w)
13 | plt.figure() # needed to avoid adding curves in plot
14 | plt.plot(t, y)
15 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
16 | if not os.path.isdir('static'):
17 | os.mkdir('static')
18 | else:
19 | # Remove old plot files
20 | for filename in glob.glob(os.path.join('static', '*.png')):
21 | os.remove(filename)
22 | # Use time since Jan 1, 1970 in filename in order make
23 | # a unique filename that the browser has not chached
24 | plotfile = os.path.join('static', str(time.time()) + '.png')
25 | plt.savefig(plotfile)
26 | return plotfile
27 |
28 | if __name__ == '__main__':
29 | print compute(1, 0.1, 1, 20)
30 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.forms import ModelForm
3 | from math import pi
4 | from django.core.exceptions import ValidationError
5 | from django.core.validators import MinValueValidator
6 | import functools
7 |
8 | def check_interval(value, min_value=None, max_value=None):
9 | """Validate that a value is inside an interval."""
10 | failure = False
11 | if min_value is not None:
12 | if value < min_value:
13 | failure = True
14 | if max_value is not None:
15 | if value > max_value:
16 | failure = True
17 | if failure:
18 | raise ValidationError(
19 | 'value=%s not in [%s, %s]' %
20 | (value,
21 | '-infty' if min_value is None else str(min_value),
22 | 'infty' if max_value is None else str(max_value)))
23 |
24 | def interval(min_value=None, max_value=None):
25 | """Django-compatible interface to check_interval."""
26 | return functools.partial(
27 | check_interval, min_value=min_value, max_value=max_value)
28 |
29 | class Input(models.Model):
30 | A = models.FloatField(
31 | verbose_name=' amplitude (m)', default=1.0,
32 | validators=[MinValueValidator(0)])
33 | b = models.FloatField(
34 | verbose_name=' damping coefficient (kg/s)', default=0.0,
35 | validators=[interval(0,None)])
36 | w = models.FloatField(
37 | verbose_name=' frequency (1/s)', default=2*pi)
38 | T = models.FloatField(
39 | verbose_name=' time interval (s)', default=18)
40 |
41 | class InputForm(ModelForm):
42 | class Meta:
43 | model = Input
44 |
45 | def clean_T(self):
46 | T = self.cleaned_data['T']
47 | w = self.cleaned_data['w']
48 | period = 2*pi/w
49 | if T > 30*period:
50 | num_periods = int(round(T/period))
51 | raise ValidationError(
52 | 'Cannot plot as much as %d periods! T<%.2f' %
53 | (num_periods, 30*period))
54 | return T
55 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/templates/vib2.html:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | {% if result != None %}
17 | {% load static %}
18 |
19 | {% endif %}
20 |
21 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/django_apps/vib2/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from django.http import HttpResponse
4 | from models import InputForm
5 | from compute import compute
6 | import os
7 |
8 | def index(request):
9 | os.chdir(os.path.dirname(__file__))
10 | result = None
11 | if request.method == 'POST':
12 | form = InputForm(request.POST)
13 | if form.is_valid():
14 | form2 = form.save(commit=False)
15 | result = compute(form2.A, form2.b, form2.w, form2.T)
16 | result = result.replace('static/', '')
17 | else:
18 | form = InputForm()
19 |
20 | return render_to_response('vib2.html',
21 | {'form': form,
22 | 'result': result,
23 | }, context_instance=RequestContext(request))
24 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/gen/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace, zeros_like
2 | import matplotlib.pyplot as plt
3 | import os, time, glob, math
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute_vib(A, b, w, T, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | t = linspace(0, T, resolution+1)
11 | y = damped_vibrations(t, A, b, w)
12 | plt.figure() # needed to avoid adding curves in plot
13 | plt.plot(t, y)
14 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
15 |
16 | # Make Matplotlib write to BytesIO file object and grab
17 | # return the object's string
18 | from io import BytesIO
19 | figfile = BytesIO()
20 | plt.savefig(figfile, format='png')
21 | figfile.seek(0) # rewind to beginning of file
22 | import base64
23 | figdata_png = base64.b64encode(figfile.getvalue())
24 | figfile = BytesIO()
25 | plt.savefig(figfile, format='svg')
26 | figfile.seek(0)
27 | figdata_svg = '
2 |
3 | {% for field in form %}
4 | {{ field.name }} {{ field }}
5 | {% if field.errors %}
6 |
7 | {% for error in field.errors %}
8 | {{ error }}
9 | {% endfor %}
10 | {% endif %}
11 | {% endfor %}
12 |
13 |
14 |
15 | {% if result != None %}
16 | {{ result|safe }}
17 | {% endif %}
18 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/gen/templates/view_results.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ result[2]|safe }}
11 | {{ result[3]|safe }}
12 |
13 |
14 | Mean value: {{ result[4] }}
15 | Standard deviation value: {{ result[5] }}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/gen/templates/view_results_default.html:
--------------------------------------------------------------------------------
1 |
2 | {% if result != None %}
3 | {% if type(result) == type("") and
4 | result[:-4] == '.png' or result[:-4] == '.gif' or
5 | result[:-4] == '.jpg' %}
6 |
7 | {% else %}
8 | {{ str(result) }}
9 | {% endif %}
10 | {% endif %}
11 |
12 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw1/compute.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def compute(r):
4 | return math.sin(r)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw1/controller.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, render_template, request
2 | from wtforms import Form, FloatField, validators
3 | from compute import compute
4 |
5 | app = Flask(__name__)
6 |
7 | # Model
8 | class InputForm(Form):
9 | r = FloatField(validators=[validators.InputRequired()])
10 |
11 | # View
12 | @app.route('/hw1', methods=['GET', 'POST'])
13 | def index():
14 | form = InputForm(request.form)
15 | if request.method == 'POST' and form.validate():
16 | r = form.r.data
17 | s = compute(r)
18 | return render_template("view_output.html", form=form, s=s)
19 | else:
20 | return render_template("view_input.html", form=form)
21 |
22 | if __name__ == '__main__':
23 | app.run(debug=True)
24 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw1/templates/view_input.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw1/templates/view_output.html:
--------------------------------------------------------------------------------
1 | Hello, World! sin({{ form.r.data }})={{ s }}.
2 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw2/compute.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def compute(r):
4 | return math.sin(r)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw2/controller.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, render_template, request
2 | from wtforms import Form, FloatField, validators
3 | from compute import compute
4 |
5 | app = Flask(__name__)
6 |
7 | # Model
8 | class InputForm(Form):
9 | r = FloatField(validators=[validators.InputRequired()])
10 |
11 | # View
12 | @app.route('/hw2', methods=['GET', 'POST'])
13 | def index():
14 | form = InputForm(request.form)
15 | if request.method == 'POST' and form.validate():
16 | r = form.r.data
17 | s = compute(r)
18 | else:
19 | s = None
20 |
21 | return render_template("view.html", form=form, s=s)
22 |
23 | if __name__ == '__main__':
24 | app.run(debug=True)
25 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw2/templates/view.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw3/compute.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def compute(r):
4 | return math.sin(r)
5 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw3/controller.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, render_template, request
2 | from compute import compute
3 | from model import InputForm
4 |
5 | app = Flask(__name__)
6 |
7 | @app.route('/hw3', methods=['GET', 'POST'])
8 | def index():
9 | form = InputForm(request.form)
10 | if request.method == 'POST' and form.validate():
11 | r = form.r.data
12 | s = compute(r)
13 | else:
14 | s = None
15 |
16 | return render_template("view.html", form=form, s=s)
17 |
18 |
19 | if __name__ == '__main__':
20 | app.run(debug=True)
21 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw3/model.py:
--------------------------------------------------------------------------------
1 | from wtforms import Form, FloatField, validators
2 |
3 | class InputForm(Form):
4 | r = FloatField(validators=[validators.InputRequired()])
5 |
6 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/hw3/templates/view.html:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/login/_generate_app.py:
--------------------------------------------------------------------------------
1 | """
2 | This file is not part of the web application in this directory.
3 |
4 | This file just applies the Parampool package to automatically generate
5 | a Flask app with login functionality. It was used as starting
6 | point for the files in this directory, but the files have been
7 | edited (and simplified) afterwards.
8 | """
9 | from parampool.generator.flask import generate
10 | from compute import compute
11 |
12 | generate(compute, default_field='FloatField', enable_login=True)
13 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/login/app.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask import Flask
3 |
4 | app = Flask(__name__)
5 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sqlite.db'
6 | app.secret_key = os.urandom(24)
7 |
8 | # Email settings
9 | import base64
10 | app.config.update(
11 | MAIL_SERVER='smtp.gmail.com',
12 | MAIL_PORT=587,
13 | MAIL_USE_TLS=True,
14 | MAIL_USERNAME = 'cbcwebsolvermail@gmail.com',
15 | MAIL_PASSWORD = base64.decodestring('RGlmZmljdWx0UFch'),
16 | MAIL_DEFAULT_SENDER = 'Flask Compute Email '
17 | )
18 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/login/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace
2 | import matplotlib.pyplot as plt
3 | import os, time, glob
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute(A, b, w, T, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | t = linspace(0, T, resolution+1)
11 | y = damped_vibrations(t, A, b, w)
12 | plt.figure() # needed to avoid adding curves in plot
13 | plt.plot(t, y)
14 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
15 |
16 | # Make Matplotlib write to BytesIO file object and grab
17 | # return the object's string
18 | from io import BytesIO
19 | figfile = BytesIO()
20 | plt.savefig(figfile, format='png')
21 | figfile.seek(0) # rewind to beginning of file
22 | import base64
23 | figdata_png = base64.b64encode(figfile.getvalue())
24 | return figdata_png
25 |
26 | def compute_png_svg(A, b, w, T, resolution=500):
27 | """Return filename of plot of the damped_vibration function."""
28 | t = linspace(0, T, resolution+1)
29 | y = damped_vibrations(t, A, b, w)
30 | plt.figure() # needed to avoid adding curves in plot
31 | plt.plot(t, y)
32 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
33 |
34 | # Make Matplotlib write to BytesIO file object and grab
35 | # return the object's string
36 | from io import BytesIO
37 | figfile = BytesIO()
38 | plt.savefig(figfile, format='png')
39 | figfile.seek(0) # rewind to beginning of file
40 | import base64
41 | figdata_png = base64.b64encode(figfile.getvalue())
42 | figfile = BytesIO()
43 | plt.savefig(figfile, format='svg')
44 | figfile.seek(0)
45 | figdata_svg = ' 0:
43 | instance = user.Compute.order_by('-id').first()
44 | result = instance.result
45 | form = populate_form_from_instance(instance)
46 |
47 | return render_template("view.html", form=form,
48 | result=result, user=user)
49 |
50 |
51 | def populate_form_from_instance(instance):
52 | """Repopulate form with previous values"""
53 | form = ComputeForm()
54 | for field in form:
55 | field.data = getattr(instance, field.name)
56 | return form
57 |
58 | def send_email(user):
59 | from flask.ext.mail import Mail, Message
60 | mail = Mail(app)
61 | msg = Message("Compute Computations Complete",
62 | recipients=[user.email])
63 | msg.body = """
64 | A simulation has been completed by the Flask Compute app.
65 | Please log in at
66 |
67 | http://localhost:5000/login
68 |
69 | to see the results.
70 |
71 | ---
72 | If you don't want email notifications when a result is found,
73 | please register a new user and leave the 'notify' field
74 | unchecked.
75 | """
76 | mail.send(msg)
77 |
78 | @app.route('/reg', methods=['GET', 'POST'])
79 | def create_login():
80 | from forms import register_form
81 | form = register_form(request.form)
82 | if request.method == 'POST' and form.validate():
83 | user = User()
84 | form.populate_obj(user)
85 | user.set_password(form.password.data)
86 |
87 | db.session.add(user)
88 | db.session.commit()
89 |
90 | login_user(user)
91 | return redirect(url_for('index'))
92 | return render_template("reg.html", form=form)
93 |
94 | @app.route('/login', methods=['GET', 'POST'])
95 | def login():
96 | from forms import login_form
97 | form = login_form(request.form)
98 | if request.method == 'POST' and form.validate():
99 | user = form.get_user()
100 | login_user(user)
101 | return redirect(url_for('index'))
102 | return render_template("login.html", form=form)
103 |
104 | @app.route('/logout')
105 | @login_required
106 | def logout():
107 | logout_user()
108 | return redirect(url_for('index'))
109 |
110 | @app.route('/old')
111 | @login_required
112 | def old():
113 | data = []
114 | user = current_user
115 | if user.is_authenticated():
116 | instances = user.Compute.order_by('-id').all()
117 | for instance in instances:
118 | form = populate_form_from_instance(instance)
119 |
120 | result = instance.result
121 | if instance.comments:
122 | comments = "Comments " + instance.comments
123 | else:
124 | comments = ''
125 | data.append(
126 | {'form':form, 'result':result,
127 | 'id':instance.id, 'comments': comments})
128 |
129 | return render_template("old.html", data=data)
130 |
131 | @app.route('/add_comment', methods=['GET', 'POST'])
132 | @login_required
133 | def add_comment():
134 | user = current_user
135 | if request.method == 'POST' and user.is_authenticated():
136 | instance = user.Compute.order_by('-id').first()
137 | instance.comments = request.form.get("comments", None)
138 | db.session.commit()
139 | return redirect(url_for('index'))
140 |
141 | @app.route('/delete/', methods=['GET', 'POST'])
142 | @login_required
143 | def delete_post(id):
144 | id = int(id)
145 | user = current_user
146 | if user.is_authenticated():
147 | if id == -1:
148 | instances = user.Compute.delete()
149 | else:
150 | try:
151 | instance = user.Compute.filter_by(id=id).first()
152 | db.session.delete(instance)
153 | except:
154 | pass
155 |
156 | db.session.commit()
157 | return redirect(url_for('old'))
158 |
159 |
160 | if __name__ == '__main__':
161 | if not os.path.isfile(os.path.join(
162 | os.path.dirname(__file__), 'sqlite.db')):
163 | db.create_all()
164 | app.run(debug=True)
165 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/login/db_models.py:
--------------------------------------------------------------------------------
1 | from flask.ext.sqlalchemy import SQLAlchemy
2 | from werkzeug import generate_password_hash, check_password_hash
3 | from app import app
4 |
5 | db = SQLAlchemy(app)
6 |
7 | class User(db.Model):
8 | id = db.Column(db.Integer, primary_key=True)
9 | username = db.Column(db.String(50), unique=True)
10 | pwhash = db.Column(db.String())
11 | email = db.Column(db.String(120), nullable=True)
12 | notify = db.Column(db.Boolean())
13 |
14 | def __repr__(self):
15 | return '' % (self.username)
16 |
17 | def check_password(self, pw):
18 | return check_password_hash(self.pwhash, pw)
19 |
20 | def set_password(self, pw):
21 | self.pwhash = generate_password_hash(pw)
22 |
23 | def is_authenticated(self):
24 | return True
25 |
26 | def is_active(self):
27 | return True
28 |
29 | def is_anonymous(self):
30 | return False
31 |
32 | def get_id(self):
33 | return self.id
34 |
35 | class Compute(db.Model):
36 | id = db.Column(db.Integer, primary_key=True)
37 |
38 | A = db.Column(db.String())
39 | b = db.Column(db.String())
40 | w = db.Column(db.String())
41 | T = db.Column(db.String())
42 | resolution = db.Column(db.Integer)
43 |
44 | result = db.Column(db.String())
45 | comments = db.Column(db.String(), nullable=True)
46 | user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
47 | user = db.relationship('User',
48 | backref=db.backref('Compute', lazy='dynamic'))
49 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/login/forms.py:
--------------------------------------------------------------------------------
1 | import wtforms as wtf
2 | from math import pi
3 |
4 | class ComputeForm(wtf.Form):
5 | A = wtf.FloatField(label='\( A \)', default=1.0,
6 | validators=[wtf.validators.InputRequired()])
7 | b = wtf.FloatField(label='\( b \)', default=0.0,
8 | validators=[wtf.validators.InputRequired()])
9 | w = wtf.FloatField(label='\( w \)', default=pi,
10 | validators=[wtf.validators.InputRequired()])
11 | T = wtf.FloatField(label='\( T \)', default=18,
12 | validators=[wtf.validators.InputRequired()])
13 | resolution = wtf.IntegerField(label='resolution', default=500,
14 | validators=[wtf.validators.InputRequired()])
15 |
16 | from db_models import db, User
17 | import flask.ext.wtf.html5 as html5
18 |
19 | # Standard Forms
20 | class register_form(wtf.Form):
21 | username = wtf.TextField(
22 | label='Username', validators=[wtf.validators.Required()])
23 | password = wtf.PasswordField(
24 | label='Password', validators=[
25 | wtf.validators.Required(),
26 | wtf.validators.EqualTo(
27 | 'confirm', message='Passwords must match')])
28 | confirm = wtf.PasswordField(
29 | label='Confirm Password',
30 | validators=[wtf.validators.Required()])
31 | email = html5.EmailField(label='Email')
32 | notify = wtf.BooleanField(label='Email notifications')
33 |
34 | def validate(self):
35 | if not wtf.Form.validate(self):
36 | return False
37 |
38 | if self.notify.data and not self.email.data:
39 | self.notify.errors.append(
40 | 'Cannot send notifications without a valid email address')
41 | return False
42 |
43 | if db.session.query(User).filter_by(
44 | username=self.username.data).count() > 0:
45 | self.username.errors.append('User already exists')
46 | return False
47 |
48 | return True
49 |
50 | class login_form(wtf.Form):
51 | username = wtf.TextField(
52 | label='Username', validators=[wtf.validators.Required()])
53 | password = wtf.PasswordField(
54 | label='Password', validators=[wtf.validators.Required()])
55 |
56 | def validate(self):
57 | if not wtf.Form.validate(self):
58 | return False
59 |
60 | user = self.get_user()
61 |
62 | if user is None:
63 | self.username.errors.append('Unknown username')
64 | return False
65 |
66 | if not user.check_password(self.password.data):
67 | self.password.errors.append('Invalid password')
68 | return False
69 |
70 | return True
71 |
72 | def get_user(self):
73 | return db.session.query(User).filter_by(
74 | username=self.username.data).first()
75 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/upload/compute.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import os
3 |
4 | def compute_mean_std(filename=None):
5 | data = np.loadtxt(os.path.join('uploads', filename))
6 | return """
7 | Data from file %s :
8 |
9 |
10 | mean %.3g
11 | st.dev. %.3g
12 | """ % (filename, np.mean(data), np.std(data))
13 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/upload/controller.py:
--------------------------------------------------------------------------------
1 | from compute import compute_mean_std as compute_function
2 |
3 | from flask import Flask, render_template, request
4 | from model import Average
5 | from werkzeug import secure_filename
6 | import os
7 |
8 | # Application object
9 | app = Flask(__name__)
10 |
11 | # Relative path of directory for uploaded files
12 | UPLOAD_DIR = 'uploads/'
13 |
14 | app.config['UPLOAD_FOLDER'] = UPLOAD_DIR
15 | app.secret_key = 'MySecretKey'
16 |
17 | if not os.path.isdir(UPLOAD_DIR):
18 | os.mkdir(UPLOAD_DIR)
19 |
20 | # Allowed file types for file upload
21 | ALLOWED_EXTENSIONS = set(['txt', 'dat', 'npy'])
22 |
23 | def allowed_file(filename):
24 | """Does filename have the right extension?"""
25 | return '.' in filename and \
26 | filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
27 |
28 | # Path to the web application
29 | @app.route('/', methods=['GET', 'POST'])
30 | def index():
31 | form = Average(request.form)
32 | filename = None # default
33 | if request.method == 'POST':
34 |
35 | # Save uploaded file on server if it exists and is valid
36 | if request.files:
37 | file = request.files[form.filename.name]
38 | if file and allowed_file(file.filename):
39 | # Make a valid version of filename for any file ystem
40 | filename = secure_filename(file.filename)
41 | file.save(os.path.join(app.config['UPLOAD_FOLDER'],
42 | filename))
43 |
44 | result = compute_function(filename)
45 | else:
46 | result = None
47 |
48 | return render_template("view.html", form=form, result=result)
49 |
50 | if __name__ == '__main__':
51 | app.run(debug=True)
52 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/upload/model.py:
--------------------------------------------------------------------------------
1 | import wtforms as wtf
2 |
3 | class Average(wtf.Form):
4 | filename = wtf.FileField(validators=
5 | [wtf.validators.InputRequired()])
6 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/upload/testfile.dat:
--------------------------------------------------------------------------------
1 | 1.1
2 | 2.2
3 | 4
4 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/compute.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, cos, linspace
2 | import matplotlib.pyplot as plt
3 | import os, time, glob
4 |
5 | def damped_vibrations(t, A, b, w):
6 | return A*exp(-b*t)*cos(w*t)
7 |
8 | def compute(A, b, w, T, resolution=500):
9 | """Return filename of plot of the damped_vibration function."""
10 | t = linspace(0, T, resolution+1)
11 | u = damped_vibrations(t, A, b, w)
12 | plt.figure() # needed to avoid adding curves in plot
13 | plt.plot(t, u)
14 | plt.title('A=%g, b=%g, w=%g' % (A, b, w))
15 | if not os.path.isdir('static'):
16 | os.mkdir('static')
17 | else:
18 | # Remove old plot files
19 | for filename in glob.glob(os.path.join('static', '*.png')):
20 | os.remove(filename)
21 | # Use time since Jan 1, 1970 in filename in order make
22 | # a unique filename that the browser has not chached
23 | plotfile = os.path.join('static', str(time.time()) + '.png')
24 | plt.savefig(plotfile)
25 | return plotfile
26 |
27 | if __name__ == '__main__':
28 | print compute(1, 0.1, 1, 20)
29 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/controller.py:
--------------------------------------------------------------------------------
1 | from model import InputForm
2 | from flask import Flask, render_template, request
3 | from compute import compute
4 | import sys
5 |
6 | app = Flask(__name__)
7 |
8 | try:
9 | template_name = sys.argv[1]
10 | except IndexError:
11 | template_name = 'view_plain'
12 |
13 | if template_name == 'view_flask_bootstrap':
14 | from flask_bootstrap import Bootstrap
15 | Bootstrap(app)
16 |
17 | @app.route('/vib1', methods=['GET', 'POST'])
18 | def index():
19 | form = InputForm(request.form)
20 | if request.method == 'POST' and form.validate():
21 | result = compute(form.A.data, form.b.data,
22 | form.w.data, form.T.data)
23 | else:
24 | result = None
25 | print form, dir(form)
26 | #print form.keys()
27 | for f in form:
28 | print f.id
29 | print f.name
30 | print f.label
31 |
32 | return render_template(template_name + '.html',
33 | form=form, result=result)
34 |
35 | if __name__ == '__main__':
36 | app.run(debug=True)
37 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/model.py:
--------------------------------------------------------------------------------
1 | from wtforms import Form, FloatField, validators
2 | from math import pi
3 |
4 | class InputForm(Form):
5 | A = FloatField(
6 | label='amplitude (m)', default=1.0,
7 | validators=[validators.InputRequired()])
8 | b = FloatField(
9 | label='damping factor (kg/s)', default=0,
10 | validators=[validators.InputRequired()])
11 | w = FloatField(
12 | label='frequency (1/s)', default=2*pi,
13 | validators=[validators.InputRequired()])
14 | T = FloatField(
15 | label='time interval (s)', default=18,
16 | validators=[validators.InputRequired()])
17 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/static/basic.css:
--------------------------------------------------------------------------------
1 | td.name { color: blue; }
2 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/templates/view.html:
--------------------------------------------------------------------------------
1 | Give input:
2 |
3 |
15 |
16 |
17 | {% if result != None %}
18 |
Plot:
19 |
20 | {% endif %}
21 |
22 |
--------------------------------------------------------------------------------
/doc/src/web4sa/src-web4sa/apps/flask_apps/vib1/templates/view_bootstrap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
17 |
20 |
31 |
32 | Damped sine wave
33 |
34 | This web page visualizes the function \(
35 | u(t) = Ae^{-bt}\sin (w t), \hbox{ for } t\in [0,T]
36 | \).
37 |
38 |
39 |