What are current options for plain arithmetic?

I just felt like some mindless coding tonight, and I was wondering what options exist that do this:

(kind of a silly example, but I’m thinking of more complex equations)

2 Likes

Beyond the native math ops, I believe @telmiger 's rpn macro is pretty close (“Reverse polish notation”) to what you ask for, but it was created before the many math ops were introduced in TW so maybe it is functionally replaced to some extend. Likewise with Evan Balsters old arithmetic solutions that took a broader approach than the rpn macro.

1 Like

Underling that. @telmiger’s RPN is very good for simple maths.

TT

1 Like

I had to look it up in the examples

All other solutions I was aware of at that time are listed in the readme of rpn

Here’s mine for plain arithmetic:

https://cjveniot.neocities.org/TiddlyWikiEvalThisMacro.html


1 Like

In addition to enabling simple things like processing arithmetic expressions, exposing javascript eval(...) through a macro wrapper is extremely dangerous, because it can be used to run arbitrary javascript code that can do very evil things.

All that is needed is a little social engineering to convince someone to import a seemingly-innocuous tiddler that has some malicious code buried in it. As soon as that tiddler is rendered… BOOM!… it can do bad things, without you even being aware.

This is particularly so when the macro definition is installed in a TiddlyWiki that has been posted online, since the javascript code will run server-side within the hosted domain, without any of the “cross-domain” protections normally associated with invoking 3rd party scripts.

-e

1 Like

I was concerned about that, so I did a little bit of testing trying to eval javascript code.

TiddlyWiki gave a nasty “this is embarrassing” error every time, so I gathered TiddlyWiki is doing something to prevent eval from running the javascript code. So something about the TiddlyWiki design that is keeping things safe?

Is TiddlyWiki not doing something to prevent the security risk we are thinking about?

Oops, I must have made an error in my testing.

Easy peasy fix to the eval function so that it only accepts numerics and arithmetic characters.

Give me an hour or two.

Is something like

{{{ [{!!a}multiply{!!b}] +[divide[2]] }}}

Not plain enough?

Yes when just dealing with just several numbers and operands.

I’m thinking more complicated arithmetic, like 1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10

So the macro reference looks like this:

<<EvalThis "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10">>

Sure

But even your example can be broken into seperate pieces then combining them at the end. In many cases there may be value in this logical arrangement effectivly allowing you to name intermediate results. Further the values can be litteral, field or text reference, a variable or the output of a previous filter step.

I understand where you are comming from however sometimes limitations are the mother of invention. In someways breaking the problem into named pieces helps clarity, readability and ourselves when we return after an absence to relearn what we were thinking before.

I will present an example tomorrow.

Yes, I know how to do it the TiddlyWiki way.

I could have done that, but I really wasn’t interested.

Great for you to put that kind of sample together to include in this thread, though.

Update: EvalThis for Simple Arithmetic — a non-linear personal web notebook

Locked down the related javascript macro to only allow the following characters to be processed, returning an error if anything else is is the expression:

  • 0123456789 ()±*/%

Anything other than those specific characters, and you get the following result:

:exclamation:invalid expression​:exclamation:

1 Like

good stuff but you need to capture errors such as

<<EvalThis “0()”>>

1 Like

Ugh. No wonder I hate javascript. I’ll play around with that.

That was close to tears painful.

Although I appreciate something silly all of the good stuff folk have done with javascript, do javascript and I ever not get along.

Regardless, thanks @buggyj !!!

Nothing fancy, but much more resilient, I think.

Whatever gets passed to the TiddlyWiki macro gets wikified before getting passed to javascript for arithmetic evaluation.

The final result of Wikification must result in a valid arithmetic expression that has nothing but the following characters (excluding double-quotes): "0123456789 ()+-*/%" (yeah, there is a space in there)

<<EvalThis "0()">> will give ❗invalid arithmetic expression❗

For those interested, the javascript behind it all:

function(expr) {
try {
    var expr_check = expr;
    for (var i = 0; i < expr.length; i++) {
        if ( '0123456789 ()+-*/%'.indexOf(expr[i]) == -1) {
            expr_check = 'crap';
            break;
        }
    }
    var sReturn = eval(expr_check);
    if ( sReturn == '' ) {
        sReturn = '0'
    }
 return sReturn;
}
catch {
 return '❗invalid arithmetic expression❗';
}
1 Like

@Charlie_Veniot - to import your creation, is all that is needed these two tiddlers, i.e the macro and the js tiddler? Very lightweight in that case - nice! Do you plan on making a plugin from it?

Yup, just those two.

Although nobody would guess from my verbose self, I do love minimalism when it comes to “solutions”.

Two wee plugins and a no-nonsense way of expressing lengthy arithmetic expressions (well, when only basic arithmetic is needed), that’s my cup o’ tea for sure.

If one needs more, my first vote is to blend with the already existing math functionality in the filter operators. If more is needed, goto them plugins.

Not a fan of the process involved in creating plugins. Maybe I’ll just setup a “package” for easy single-file drag’n drop.

I kind of like the idea of folk being able to rename/organize those two tiddlers however they like, or even just nab the code (well, that one TW macro, maybe best to leave the javascript one alone) to put into tiddlers they have already. A “weave into your stuff as per your preferences” philosophy?

Actual I withdraw this offer on your example 1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10 because it is itself mathematically unnecessarily complex. for example the innermost parentheses need not be 3+ then -9 (only -6). Clearly you got the monkeys at a typewriter #1, to generate a random calculation :nerd_face:

Here is the simple interest formula as an example of my argument, which is not deigning your need, simply demonstrating a valid alternative, to addressing the thread “What are current options for plain arithmetic?”.

Place this in a tiddler on tiddlywiki.com
Here is the simple interest formula as an example.

<$let 
principal=5000 
interest="0.02"
years="10" 
percent-interest={{{ [<interest>multiply[100]] }}}
dollar={{{ [<interest>multiply<years>add[1]] }}}
total-interest={{{ [<dollar>multiply<principal>] }}}
total-repayments={{{ [<principal>add<total-interest>] }}}
months={{{ [<years>multiply[12]] }}}
monthly-repayment={{{ [<total-repayments>divide<months>] }}}
>

;R = P (1 + rt)
* Principal (P) $<<principal>> 
* Interest rate (r) <<percent-interest>>% over <<years>> years (t) 
* Total interest= $<<total-interest>>, thus Principal + Interest = <<total-repayments>>
* Monthly repayments = $<$text text={{{ [<monthly-repayment>round[2]] }}}/> over <<months>> months.

</$let>

This approach has a number of advantages;

  • Plain english variables
  • All intermediate values available
  • Easy and readable opportunities to display the results in many ways.
  • Can replace the “input values” with tiddler, field or variable references
  • Easy to manually edit input values.
  • Easy to reuse / can transclude if using current tiddler fields as input
  • Can move the input values outside of the formulae.

#1 I also enjoy The Infinite Monkey cage

I picked an example related to recent work parsing arithmetic equations, which is what had me thinking about how best to handle complex arithmetic in TiddlyWiki.

From https://rosettacode.org/wiki/Arithmetic_evaluation#BBC_BASIC:

Input = 1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10
AST =   ((1)+(2*((3)+(((4*5)+(6*7*8)))-(9))/10))
Value = 71

Related for your amusement:

I’ve seen complex enough arithmetic equations in my day to see value in a simple EvalThis arithmetic expression macro.

I just couldn’t think of any off the top of my head.

How about the distance formula to find the distance between two points in a plane?

Screenshot 2022-03-12 9.25.01 PM

Do you want us to try that one?

2 Likes