Skip to main content

education - Making an application based on user input


I purchased Mathematica a few days ago, and although I am a mathematician, my programming and Mathematica knowledge is close to zero. So please help and point me to some resources for the following use.


I intend on making some educational materials for my students in the form of web apps. I started learning some basic HTML and JavaScript, but then I found the amazing CDF and HTML integration that Mathematica offers. So I thought it would be more useful, powerful and easy to program some math-based algorithms in Mathematica and use them in HTML.


So, long story short: how can I make an "application" in Mathematica where the user enters a value and the program outputs the result of some algorithms applied to that value?


Concrete example: The Collatz algorithm: The user enters a number $x$, then the program halves it, if it is even or computes $3x+1$ if it is even, all of this while $x \neq 1$. I want an InputField for the user to enter $x$ and after pressing Enter, the program to print the steps that the algorithm makes down to $1$.


Yes, I know, the Collatz algorithm is easy to implement in any (other) language, I just offered it as an example which would be easy for me to understand.


Actually, I can ask something else: would you say Mathematica is best suited for computations and I'd rather use something else for programming math based utilities for my students?



Answer



28/2/2018: Wolfram Cloud now supports (quite possibly since several years ago) cross origin requests, so that part of this answer can be ignored. Ajax may be used, just remember to set the API permissions to "public".


Support for the mechanism that makes the CDF browser plugin possible is being phased out, and the CDF player already does not work on the newest versions of Google Chrome. In light of this there is no better time than now to start mixing the Wolfram Language with HTML and Javascript.



The concerns of using Wolfram Language as a backend/server language is no different than when using some other server language. You always have to ask yourself whether you want to implement a certain functionality in the frontend or in the backend. Since Javascript is not very good at math there will probably be lots of time that even a Javascript expert would choose to use the Wolfram Language.


Getting started


In order to get started you need a good HTML/CSS framework and a good Javascript framework that contain all the things you need so you don't have to write them.



  • I recommend to start using Bootstrap for building your designs. The documentation is very nice and it has most of the things you'll need.

  • For Javascript I recommend jQuery which the most popular Javascript framework by far. The documentation is good, there are lots of tutorials online and there are many "plugins" available that provide additional functionality.


I will use this combination in my examples below.


How to deploy Wolfram Language


Wolfram Language provides CloudDeploy and APIFunction which combine to create a RESTful API, and this is how we will call on our Wolfram Language code.



Websites such as Mathematica.Stackexchange or New York Times rely heavily on backend scripts/RESTful APIs. They run Javascript in the frontend that call these scripts when it is appropriate to update the content that the user sees. The technique they use is called "AJAX". Unfortunately it is one thing to send an AJAX request to New York Times' server from newyorktimes.com and it's another thing to send an AJAX request to New York Times' server from your own website. Such "cross domain requests" have been prevented by browsers since the inception of AJAX, and browsers only recently started allowing them and only if the server respond with a specific "header". WRI's server does not respond with this header, which means that we cannot communicate with it using AJAX.


We will see later that this does not matter for images, because we don't need AJAX for those. But it matters when the result is data. Luckily there is a workaround known as "jsonp". It's not the normal type of AJAX, but it works like it. That's what we will be using instead. jQuery will take care of most of the work behind the scenes, but we need to modify our APIFunction as well. This auxiliary function will take care of that:


jsonpAPIFunction[args_, f_] := APIFunction[
Append[args, "callback" -> "String"],
StringJoin[#callback, "(", ToString@f[#], ")"] &,
"String"
]

BMI counter


In order to create a BMI counter we need to create a form that lets the user input his height and his weight. Then we need to apply the BMI formula to these numbers and show the result. Since this is an exercise in how to do computations with Wolfram Language, not Javascript, the formula (weight/height^2) will be computed in the cloud. In fact this is the APIFunction:



CloudDeploy@jsonpAPIFunction[{
"weight" -> "Number",
"height" -> "Number"
},
N[#weight/#height^2] &]

The Javascript and HTML is appended to the end of the post, you will see that only very little code is needed. There are instructions there as well that explain how you can try this yourself. This animation shows how smooth it works, even though it asks for the BMI from a server instead of computing it locally:


BMI counter


Domain coloring


This example, which you can also try with the code at the end of the post, is meant to show how to handle APIs that return images. In order to build the example I took Simon Woods' domain coloring function from this question. You have to define his domainPlot function as well, after that you can use this APIFunction:



deployableDomainPlot[assoc_] := domainPlot@ToExpression@assoc["f"]
CloudDeploy@APIFunction[{
"f" -> "String"
},
deployableDomainPlot,
"PNG"
]

The result will look like this:


Domain coloring



HTML/CSS/Javascript Manipulate clone


This example is not included in the code at the end of the post, but I thought I might show the result anyway. It works the same way as the domain coloring example above but the interface is a bit more complicated. I made it with jQuery, jQuery UI and a jQuery tooltip plugin.


Example Manipulate


HTML/CSS/Javascript code


Here is the code you need to test the first two examples above. Note that you need to run the CloudDeploy code given for the examples above to generate your own API URLs. Then you have to put the URLs into the Javascript code, which is in the beginning of the document, in the part of the document.










Wolfram Language API examples
















Wolfram Language API examples



BMI calculator




















Result


Undefined




Domain coloring














Result


Undefined








Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....