Introduction: DIY Web Calculator for Scientists

About: I'm an applied physicist by training(phd Yale 2006, BA Berkeley 1998, math and physics), and have done physics research in the federal government and product development in the private sector, starting two of …

I, like most people in the physical sciences, do a LOT of calculations on computers. I've done calculations in Matlab, Mathematica, BASIC, C, Processing, LabVIEW, Igor, Python, Google Calculator, and various scripting languages. And I'm honestly pretty unhappy with all of them.

One of the most irritating aspects of most of the scientific computing options is the lack of portability. Supposedly all these tools are helping us to communicate with both peers and the public, but they mostly are totally inaccessible to the public at large, and often not only do our peers use different software from us, if you wait 4 years you also have switched to another software tool, making old files unreadable(I finished grad school in 2006 and will never be able to read any of the data analysis files from my theses work since they're all in an obsolete and proprietary format).

I believe that one solution to this is the web calculator. By "the web", I don't mean the Internet in the sense of the set of all computers connected together, I mean that the code for the calculator runs IN THE BROWSER. The web browser makers have done something truly world-changing that those of us in research physics have not really taken sufficient note of: built a truly universal computation machine. That machine consists of the set of all code that follows the basic standards for what the browsers can all read.

Contrast this with the "app" world that has grown up around all the various hardware. If you write software that runs natively on apple computers, iphones, android, microsoft phones, PCs, or embedded machines, none of them are cross compatible, and in the case of the phones you actually have to pay just to get your stuff shared in a useful way. And after you finally get a thing working it will immediately break if you don't constantly update it to follow the latest changes in the OS. But if you write a scientific application in the combination of:

  • html(describes the structure and words of the document)
  • CSS(describes the format)
  • JavaScript(makes things happen)

it will run on ANYTHING. From a Raspberry Pi to an Apple Watch to a regular Windows desktop PC, and on a half dozen browsers, if you follow the set of rules of the "open web", *everyone* will be able to run your software. And if you share it on the Web the whole rest of your field can actually DO your computations the instant you publish them.

This tutorial is to take someone who knows scientific computing but nothing at all about the Web or Web coding through the process of making a useful calculator and putting it on the web. I'll try to define as many of the web jargon terms as I can(I had to learn them over the last year by furiously googling them all and still only know a few, but I can make a calculator with what I know so it should be enough).

Step 1: Install a Text Editor, Update Your Browser

First of all, to do this you need a computer that you can install things on. Not a tablet or phone, but an actual laptop or desktop, and it doesn't matter what OS is on it, they all work.

The first software you want to install is some type of text editor designed for code. There are many free ones for all platforms, but it's important to find one that has highlighting based on what language you're using. Most of them cover an absurdly long list of languages, and all should include the three we care about here which are html, javascript, and CSS. On my Mac laptop, I use BBedit, and one option that I think works on all platforms which is free is Microsoft's Visual Studio Code. Note that until you save a file with a file extension that marks what kind of code it is, the highlighting won't be turned on. That will come in the next step.

So the first step is to go download this text editor, make sure you can open it and see how to save a file. The other piece of software you need to get started is a up to date web browser. Your current browser is probably already up to date enough for our purposes but basically I just am adding this step in case you're using a 10 year old version of Internet Explorer for some reason. If you are, update it. Once you have a modern version of any of (safari, firefox, IE, Opera, Chrome) you should be all set, regardless of which one.

Step 2: Make an HTML File, Save It, Open It

Now open a new file using the text editor you just installed and copy/paste the following into it:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2>Here is a heading</h2>
Here is some text, with some <b>bold</b> and <i>italic</i> words. 
<p>
Here is a second paragraph with a "p" tag to separate it.
</body>
</html>

After you copy this into your text editor, save the file "test.html" somewhere you can find it such as your desktop. Now open this file with a web browser by just double clicking on it, which should open it in your default web browser. It should look like what you see in the screenshot of my browser(Firefox). I have also included a screen shot of the text editor to show what the highlighting looks like.

You have now made an html file! This is the most important leg of the three legged stool that is html+CSS+JavaScript.

Step 3: Typeset an Equation Using MathJax

I left out one important piece of software for doing math on the Web because you don't need to run it on your local machine, it runs on a remote resource you get off the web. It's called "MathJax", and it's a system for typesetting math so that it actually looks like math instead of a bunch of nonsense. It's based on the LaTeX typesetting system. If you're familiar with this, being able to put it on the Web will probably sound awesome to you. If not, well,I think all people doing physical sciences should learn it, but for the purposes of this tutorial just follow along and you'll see that the basic syntax is familiar in most cases. If you want to know how to do something else, google "latex [thing you want to do]" and someone will probably have written about it. The LaTeX user community is pretty good at documenting their stuff.

Anyway, as before, we'll do a copy/paste example. Now, go back to test.html and change it to:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
$E = mc^2$
</body>
</html>

Note the changes. First we added a line with a long URL. This is the remote resource that has all the vast amount of information required to make a pretty looking equation. It can be installed locally in theory but I think it's much easier to just use the remote resource since it's constantly being updated. "cdnjs.cloudflare.com" is a third party site that the MathJax people use to host the code since the bandwidth used for this is large in total(it's on a very large number of sites, some of which are huge).

The other thing I added was the equation itself, which will be part of the final calculator. It's just the equation in a simple and familiar format with the carrot "^" representing the power, between two dollars signs. The double dollars sign both converts to math mode and sets the equation apart from all other text, centered on its own line.

More information on MathJax can be found here:

https://www.mathjax.org

Check it out. It's awesome. If nothing else I would argue that the existence of MathJax means that a lot of what we do in straight LaTeX should be converted to HTML and use this instead of compiling to pdf, but that's a whole other story. I've included screenshots of the sponsors and partners of MathJax, and it's a sort of who's who of people doing huge math things on the Web. That's important because it's why I feel it's ok to rely on for archival quality published work--this software resource is here to stay because numerous separate and well funded groups are all working on it, all in the open.

Anyway, save that file, and reopen test.html and you should see the properly typeset equation as shown in my screenshot. Try this again with some other equations such as:

$$E = mc^2$$
$$E = h\nu$$
$$A = \pi r^2$$
$$S = k\log_e{\Omega}$$
$$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2b}$$
$$F = \frac{d\vec{p}}{dt}$$

Don't forget to refresh your browser each time you change the file! This is either control-R or command-R depending on what system you're on. But in general the workflow of this whole thing is that you want both the text editor and your browser open at the same time on the same file as you work, then every time you make a change to the code, you save it, refresh the browser and you see what that change did.

Step 4: Use CSS to Format Your Html File

CSS stands for "cascaded style sheets". I thought when I started this "I'm a scientist, not a web designer so this is not my problem." However, I learned that just as you don't have to be a novelist to comment your code(and you should always comment your code) you don't have to be a web designer to use a couple simple commands to make your web content tolerable to look at. The good news is that it's very easy!

By far the best tutorial I've found on this topic is at w3schools.com, which also covers html and javascript(I learned all three from this one site). Here is the link. Also as with all this code stuff it seems the main documentation is to google "[name of language] [name of your problem]" over and over with different phrasings of your problem until you find a link to an exact solution.

Anyway, to actually do this, copy/paste the following into your file test.html:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
<div class = "calculator">
<h2>My Calculator</h2>
$$E = mc^2$$
</div>
<style>

html {
	height: 100%;
	background: black;
	background-size: cover;
}

.calculator{
	width: auto;
	height: auto;
	border-style: solid;
	border-width: 5px;
	border-color: blue;
	border-radius: 15px;
	padding: 5px 5px 5px 5px;
	margin: 5px 5px 5px 5px;
	background: white;	
	font-size: 14px;
	font-family: "Century Schoolbook";
	text-align: left;
	float:left;
}

</style>

</body>
</html>

Let's go through this to see what's happening. First of all I put our equation inside a "div" tag, and note that this gets closed with the forward slash as in all html tags. This gets put in the class I define as the "calculator" class by adding, inside the angle brackets(be sure to have a space after "div"), class = "calculator". Having defined this class, I can now do things to it both with CSS and later with JavaScript.

CSS is a huge topic that many smart people have devoted their lives to, and there are vast libraries of external CSS files you can use--but we're going to skip all that, and just use a few commands inside the file. In this mode all CSS goes inside the "style" tag as you can see. A word with no period or number sign before it indicates a tag type, like html or p for paragraph, and this tells everything in that category how to look. I do that to html to make the background black all the time(you can change this to any color, try that). Then the rest of the style code is all defining attributes of the calculator class. This is how you set font, colors, margins, padding etc(see the linked w3schools tutorial on CSS). You can mostly just pick something and leave it alone which is, in my mind, the point of CSS for technical work.

Again, copy/paste, save and reload your browser and you should see the equation above. Now this looks like some math you might actually show to the world! It just needs to actually do things now.

Step 5: It's Alive!!! (add JavaScript Code)

Now we're finally going to make the calculator calculate!

First, I'll start with the code for copy/pasting into your test.html file:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
<div class = "calculator">
<h2>My Calculator</h2>
$E = mc^2$
<p>
m = <input id = "minput" value = "1"  onchange = "computeE();"></input>kg
<p>
E = <input id = "Einput"  onchange = "computem()"></input>J
<p>
</div>
<script>

computeE();// without this "E" is empty when we first load
function computeE(){
	m = document.getElementById("minput").value;
	c = 3e8; //speed of light in meters per second
	E = m*c*c;//  <---- this is the actual equation!
	document.getElementById("Einput").value = E.toExponential();//get value from input
}
function computem(){
	E = document.getElementById("Einput").value;
	c = 3e8;
	m = E/(c*c);//inverse of the famous equation, m =E/c^2
	document.getElementById("minput").value = m;
}


</script>
<style>

html {
	height: 100%;
	background: black;
	background-size: cover;
}

.calculator{
	width: auto;
	height: auto;
	border-style: solid;
	border-width: 5px;
	border-color: blue;
	border-radius: 15px;
	padding: 5px 5px 5px 5px;
	margin: 5px 5px 5px 5px;
	background: white;	
	font-size: 14px;
	font-family: "Century Schoolbook";
	text-align: left;
	float:left;
}

</style>

</body>
</html>

I changed the html to add two "input" tags, which are each followed by the appropriate units, "J" for joules and "kg" for kilograms. For more information on the input tag see the w3schools page on forms and the documentation on the Mozilla site. There are lots of other inputs you can use, including the radio button which is very useful. Note that for each input element I gave them a logical name in the form of the id, with id = "minput" and id = "Einput". Note that these quotes are needed! These id's are what will then let us interact with those inputs in code. Also, note that each input has a onclick attribute, which is set to the name of a function defined in the code below.

Just as CSS lives inside the "style" tag or in external .css files I don't plan to use, JavaScript lives inside the "script" tag or in external .js files that I mostly don't use(expect for calling MathJax). Also note that JavaScript is totally separate from "java". This overlapping name is deliberate, and there's a whole story there if you care(it's not important as far as I can tell, though). For details on what this language is, see the Wikpedia entry and the tutorials on w3school as well as the Mozilla documentation which can be found by googling whatever you want to know about.

The code itself consists of two functions, one for each potential input(so the calculator can go both ways) and an execution of the one that goes from mass to energy so that energy is populated when the browser first loads. Each function starts out with an expression like this:

m = document.getElementById("minput").value;

This is using something called "the DOM" for "document object model", which is the basis of all calculator-like behavior. Essentially it is a conceptual framework that all the various types of software that interact with the web page can use to name things and interact with them. It can be used to create and destroy elements, change their values, and do just about anything you can do by hand in a text editor in an automated way on the fly. Mostly we'll just use one thing over and over, the "getElementById" method. Note that using periods to connect words which do things is part of "object oriented programming", and if that's something new to you (it was to me) just read lots of code to get the idea, it's much simpler than it at first looks when you first see it. You don't need to know much about objects to use them, in my experience. Also, you can copy/paste from this file over and over and really not think about it much if your calculator is similar to the one I've made in general form. With the ability to both get and set values, we just need to do the actual math, which is in a mostly obvious format. Note that we can't use "^" for power here, unlike in LaTeX, since that's used for bitwise XOR in JavaScript. There are other options, but I'm just multiplying c by c.

This is it! You've now made, by copy/paste, a working calculator. If you change the numbers and hit "enter" it should update the other number. Note that the number of Joules is so high that you probably have no intuition for that level, which is an odd thing about that being the most famous equation ever. If you want to try changing some part of it, just edit the main expression, which I marked in the comments. Be careful if you change names of things to keep capitalization consistent since everything is case sensitive.

Step 6: Apply Useful Units

As I said in the previous section, this calculator works, but is a bit hard for most of us to engage with. You either have so few kg that you have no idea what you're looking at or so many J that you also have no idea. So I'm going to do something you should almost ALWAYS do in making a custom calculator like this: rework the units to be directly relevant to something. In this case I'm going to convert to megatons of TNT.

Again, I'll now just include the code for you to copy/paste:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
<div class = "calculator">
<!--This is what an html comment looks like-->
<h2>Calculator Demo</h2>
<!--Start with the sybmolic expression, using double dollar signs to make a clean standalone equation-->
$$E = mc^2$$
<p><!-- "p" means paragraph and we need that to make a line break to make things look good-->
m = <input id = "minput" value = "1"  onchange = "computeE();"></input>kg
<p>
E = <input id = "Einput"  onchange = "computem()"></input>J
<p>
$$1 \textrm{ J}\left(\frac{\textrm{1 megaton}}{4.18\times10^{15}\textrm{ J}}\right)$$
<p>
<center>= <span id = "megatons"></span> megatons TNT</center>
</div><!--"div" means division(as in dividing up a document, not dividing numbers), and this is the type of element the "calculator" class will generally describe(but it doesn't have to!)-->
<script>
/*  <--- this / and * comment is like C and a whole lot of other languages; it works in javaScript but NOT in html
Anything inside the "script" tag is JavaScript, a language which runs in your browser and was created to be used in conjunction with html and CSS.  All actual functions to actually perform math or change values of variables exist in this language, and are in a script element that comes after the inputs that have the numbers the user reads and writes.
*/
computeE();//
function computeE(){
	m = document.getElementById("minput").value;
	c = 3e8;
	E = m*c*c;
	document.getElementById("Einput").value = E.toExponential();
	document.getElementById("megatons").innerHTML = Math.round(E/4.18e15);
}
function computem(){
	E = document.getElementById("Einput").value;
	document.getElementById("megatons").innerHTML = Math.round(E/4.18e15);
	c = 3e8;
	m = E/(c*c);
	document.getElementById("minput").value = m;
}
</script>

<style>
/* <--- this is how comments are indicated in CSS, just like JavaScript and about 100 other computer languages. 

Everything inside the style tag is CSS, or Cascaded Style Sheets.  This code determines how things will look in a document.  A tag like html or p or div here indicates how all things in that category should look.  A word beginning with a "." describes a class of elements, and a word beginning with a "#" refers to a specific element described by its id(which is also referenced by the javascript)
*/
html {
	height: 100%;
	background: black;
	background-size: cover;
}
/*
By creating a class called "calculator" we set up to be able to re-use this in a document that has more than one calculator, and have all of them look the same(whatever look you decide for that later).
*/
.calculator{
	width: auto;
	height: auto;
	border-style: solid;
	border-width: 5px;
	border-color: blue;
	border-radius: 15px;
	padding: 5px 5px 5px 5px;
	margin: 5px 5px 5px 5px;
	background: white;	
	font-size: 14px;
	font-family: "Century Schoolbook";
	text-align: left;
	float:left;
}

</style>
</body>
</html>

Now, I've put a whole bunch more comments in since this is the final version, so that what you have at the end is self-documenting. I will resist the temptation to go on and on about units, but note that to make units non-italic inside an equation we use \textrm{} with the unit inside the curly braces. Personally I think that being very explicit in both the LaTeX code and the javascript, and commenting the latter for the unit conversions is one of the most important steps of making a custom calculator, which is why I put it separate in this tutorial. Don't be surprised if you spend 4x more time fiddling with the units to get them right than you did writing the basic calculator.

Step 7: Publish to Web

I'm going to assume that like me a few months ago, this is new to you. This is as far as I can tell the least painful way to get a minimal thing onto the Web for those of us who are not developers or designers or whatever. We will use Github's web hosting feature, which is free for individuals. If you work for a big company or university or government agency they probably already have lots of things on github. None of this is your problem right now, however. Right now you just want to

  1. go get a new account, signed up as an individual.
  2. create a repository called "[yourusername].github.io" using the built in GUI on the github site.
  3. create a file in that directory called "index.html"
  4. copy your calculator in there
  5. save it, wait a few seconds or couple minutes, and go to [yourusername].github.io, and you should see your calculator live on the real web!
  6. Install GitHub Desktop on your home machine, and figure out how to use it
  7. clone your web page repository somewhere you can easily find it on whatever machine you normally work on
  8. publish all your applied math as a sequence of calculators
  9. share!

I truly believe this is how all science communication should work. ALL OF IT!!! I think that when we publish results those publications should always have live updated calculators like this so that peers can instantly play with the numbers themselves. I don't think any other system, be it python, mathematica, matlab, or something else can possibly compare to the universality of the open web like this. If you push all your math out like this, anyone with any web connection/device in the world can connect to the science you produced. Ideally, I think there should be a sort of mathematical version of Twitter, where people who work with equations are constantly pushing stuff to the feed, which subscribers(colleagues) can interact with in real time. It's ludicrous that as all communication becomes more and more real time, peer review is continuing to get slower and more broken over time. If we all published this way peer review would be not only faster but MUCH better, with everyone from your retired former colleagues to some over-caffeinated teenager in the developing world can instantly try your result and see if it works.

Note also that none of this means abandoning existing workflows. If you make everything in html, you can always use Pandoc to convert it to LaTeX, then publish it as pdf as normal. But I think that's the wrong approach. Ideally I think the following should all be in html:

  • outreach to the public
  • textbooks
  • homework
  • lab notebooks
  • instrument documentation
  • plotting software
  • analysis software
  • all peer reviewed publication

To do this no one needs to write a single monolithic tool like Mathematica, we just need to all learn how the existing tools work and start using them(because the Web people already wrote amazing tools)!