To create dynamic and useful calculators, it is important to be able to leverage ConvertCalculator's powerful formula system named FormulaScript.
Introduction
First of all, what exactly are formulas? Formulas are a collection of operations on values to produce a result. Right.. that does not seem to help, but let's start with an example. 1 + 2
is a formula that, when calculated, produces the result 3
. In this example 1
and 2
are values, addition is the operation (denoted by the operator +
), and 3
is the result. As you would expect, FormulaScript has all the common arithmetic operators: +
for addition, -
for subtraction, *
for multiplication, /
for division, and ^
for exponentiation.
FormulaScript conforms with the standard operator precedent, but you may use brackets to change the order in which the operations are run: 3 * (1 + 2)
. Note that +
and -
have a dual function since they can be used to add and subtract two values but can also be used to make a value positive or negative, respectively: +(5 - 10)
and -(5 + 10)
.
Basics
Until now FormulaScript seems like a glorified calculator, but FormulaScript offers more powerful features that allow you to build interesting calculators.
Numbers
As shown above, you can use numbers in your calculations. Numbers can be whole numbers such as 1
, 2
, and 912748127
, but they can also have fractional values behind the decimal separator .
such as 1.5
, 0.37182
and 1.0
. Note that for decimal numbers that lead with a 0
, you can omit this 0
, so 0.23
can also be .23
. To improve readability for large numbers, you can insert _
to separate the digits, e.g., 1_000_000
, note that the underscores have no meaning and are disregarded entirely, meaning they can be inserted anywhere in the number except at the start, e.g. _10
.
Strings
FormulaScript also allows you to work with textual data known as strings. Strings are any text enclosed by quotes e.g., "This is a string"
and "Strings can also have numbers 1191847"
and 'Strings can be enclosed by single quotes as well'
. To combine two strings, you can use the concatenation operator &
e.g., "A" & "B"
to get "AB"
. It is possible to use quotes inside strings. Just make sure the outer quotes are not used within the string e.g., "This is a 'string' with quotes"
or 'this is a "string" with quotes'
.
Booleans
Sometimes it is useful to encode if values are true or false. In such cases, it is entirely possible to use the numbers 1
and 0
to define true or false. However, since this is a common pattern, FormulaScript allows you to use the literal words true
and false
. Note that these words are case-insensitive, so you could also write True
, FALSE
, or even tRuE
. Boolean values by themselves are not extremely useful, but boolean values happen to be the results of comparisons.
Comparisons
Comparisons are how you compare two values with each other. For example, you could check if a number is smaller than another number 10 < 15
, and in this case, the result of this comparison is true
because 10
is smaller than 15
.
- To check if two values are bigger or smaller you can use
>
and<
respectively. - To check if two values are greater or equal use
>=
or less than or equal use<=
. - To check if two values are the same you can use
=
e.g.(10 + 1) = 11
. - To check if two values are NOT similar use
<>
e.g.10 <> 11
.
You can use compare strings too, but only to check if they are the same e.g., "A" = "A"
or "A" <> "B"
.
Note that comparisons have the lowest precedence in formulas, so 2 < 1 + 1
is interpreted as 2 < (1 + 1)
.
Functions
The real power of FormulaScript comes from functions. Functions are collections of code written for you to achieve some common or even complex case. To use a function, you must first define its name, then give the arguments, delimited by commas or semicolons, enclosed by parentheses: FUNCTION(argument_1, argument_2; argument_3, ...; argument_n)
. Note that function names are case-insensitive. ConvertCalculator provides a lot of functions for different use cases such as logical operations, financial and statistical calculations, and math functions. To see a full list of functions, refer to this overview.
References
Now all of these features are useless if you cannot interact with dynamic values which come from your forms. FormulaScript allows you to reference values by a name. The names you can use depend on the elements you have added to your calculator as well as the variables you have added. A common name is QA
, which is the default name for the first question element you added to your calculator. To use this value, you can reference it in a formula either by itself, then it will just return the value QA
, or in some sort of calculation (QA * 5) - 10_000
. Every feature explained above allows references instead of a normal value.
Comments
Comments allow you to give context to your formulas without affecting the calculation result. Comments are ignored by FormulaScript and thus are just meant to help you better maintain your formulas.
Syntax
// <any text here>
comments start with two forward slashes and end at the end of the line. This means comments can occupy an entire line or just after a part of your formula.
Examples
// this is a comment
12 * QA // and so is this
This comment explains why this formula is needed
// we give an 80% discount on orders over 100_000
IF(QA > 100_000, QA * 0.8, QA)
Intermediate Results
Due to the fact that formulas are a single expression that evaluates to a result, having complex values in formulas requires a lot of nesting. This nesting can make formulas unreadable and unmaintainable fast. Moreover, formulas might have recurring calculations that you would like to reuse, but without intermediate results, you would need to copy-paste these recurring calculations into your formula. Intermediate results solve this problem by allowing you to extract parts of your formulas into named variables, which you can reference in the main formula.
Syntax
<name> := <expression>
where name
is an identifier that you can use later in other parts of your formulas and expression
is any other valid formula (note: this expression cannot itself contain intermediate results!).
Intermediate results must be defined above the main formula! So a valid formula containing intermediate results would have the following syntax.
<name> := <expression>
<expression>
Examples
For example, the following formula calculates a certain price depending on the number of days. If that price is greater than 1 million, it applies a discount of 10%. Otherwise, it returns the normal price. This formula reuses the total price based on the number of days three times!
IF((34.50 * 24 * 60 * 60 * days) > 1_000_000, 34.50 * 24 * 60 * 60 * days * 0.90, 34.50 * 24 * 60 * 60 * days)
Rewriting this formula with intermediate results would result in the following formula
total_price := 34.50 * 24 * 60 * 60 * QA
IF(total_price > 1_000_000, total_price * 0.90, total_price)
Lambda (custom) Functions
Formulas can contain calls to functions that do/calculate a certain thing, e.g., IF
, CONVERT
and ROUND
. These functions come with FormulaScript, but it is also possible to create your own functions. These custom functions are extremely useful when used with the following built-in functions MAP
, FILTER
and FIND
(see examples below).
Syntax
FUNCTION(<expression>)
where expression
is any valid formula OR FUNCTION(<parameters>: <expression>)
where parameters
are the names of the parameters your function accepts and expression
same as the first case.
Examples
The following formula creates a function that accepts no arguments and returns a value that is 1
plus 1
. That function is then immediately called, which would produce (in this case) the value 2
.
FUNCTION(1 + 1)()
The following formula creates a function that accepts a single argument x
and returns a value that is 1
added to x
. That function is then immediately called, which would produce (in this case) the value 2
.
FUNCTION(x: x + 1)(1)
As described below, custom functions are useful with certain other functions. The following formula creates a function that is used by MAP
to square every element of an array.
MAP(ARRAY(1, 2, 3, 4, 5), FUNCTION(x: x^2))
This would produce the following output: [1, 4, 9, 16, 25]
The following formula creates a function that is used by FILTER
to keep only elements that are even.
FILTER(ARRAY(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), FUNCTION(x: MOD(x, 2) = 0))
This would produce the following output: [2, 4, 6, 8, 10]
.