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 - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

equation solving - Invert and fit implicitly defined curve

I need to fit an implicitly defined curve. I thought I could get some data out of Solve , and then using FindFit . Therefore, I would like to find the relation the parametric curve defined by $F(x,y)=0$: Solve[-(1/2) + 1/2 (0.41202 BesselK[0, 0.1 Sqrt[x^2 + y^2]] + (0.101483 x BesselK[1, 0.1 Sqrt[x^2 + y^2]])/Sqrt[x^2 + y^2]) == 0, y] But I can't get an output: Solve was unable to solve the system with inexact coefficients or the system obtained by direct rationalization of inexact numbers present in the system. Since many of the methods used by Solve require exact input, providing Solve with an exact version of the system may help. >> Edit: In particular, I would like to fit the data coming from the curve with the expression of another curve, and not with a function $f(x)$. In particular, since this clearly looks like a cardioid , I would like it to fit to something like it. What other strategies could I try?

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...