(= ( sum([tag[Profits]get[value]]) - sum(tag[Expenses]get[value]]) ) * {{Tax!!rate}} =)
<svg viewBox=<<formula " '0 0 ' & {{!!width}}*2 & ' ' & {{!!height}}">> >
Hello, all —I got fed up with the lack of good number-crunching capabilities in TiddlyWiki, and after griping about it for a year I fixed it.
Introducing the Formula plugin: http://evanbalster.com/tiddlywiki/formulas.html (version 0.1.0 at time of posting)Source and issue tracking on GitHub: https://github.com/EvanBalster/TiddlyWikiFormula
Formula is implemented as a widget, with a special (= "mushroom bracket" =) syntax for inclusion in WikiText. It supports filters, transclusion and variables, can process other formulas included via those mechanisms, and automatically refreshes like the rest of TiddlyWiki.
(= ( sum([tag[Profits]get[value]]) - sum(tag[Expenses]get[value]]) ) * {{Tax!!rate}} =)A macro allows formulas to be used as attributes (pending proper integration with the wiki parser):
<svg viewBox=<<formula " '0 0 ' & {{!!width}}*2 & ' ' & {{!!height}}">> >I'm modeling most of the syntax and behavior after popular spreadsheet software (Microsoft Excel and Google Sheets) and have implemented a decent library of math functions so far. While I don't plan on making a full spreadsheet UI, I'm working on support for cell numbers and ranges in formulas (so others can do so).
Hello, all —I got fed up with the lack of good number-crunching capabilities in TiddlyWiki, and after griping about it for a year I fixed it.
Introducing the Formula plugin: http://evanbalster.com/tiddlywiki/formulas.html (version 0.1.0 at time of posting)
Source and issue tracking on GitHub: https://github.com/EvanBalster/TiddlyWikiFormula
Formula is implemented as a widget, with a special (= "mushroom bracket" =) syntax for inclusion in WikiText. It supports filters, transclusion and variables, can process other formulas included via those mechanisms, and automatically refreshes like the rest of TiddlyWiki.
(= ( sum([tag[Profits]get[value]]) - sum(tag[Expenses]get[value]]) ) * {{Tax!!rate}} =)A macro allows formulas to be used as attributes (pending proper integration with the wiki parser):
<svg viewBox=<<formula " '0 0 ' & {{!!width}}*2 & ' ' & {{!!height}}">> >I'm modeling most of the syntax and behavior after popular spreadsheet software (Microsoft Excel and Google Sheets) and have implemented a decent library of math functions so far. While I don't plan on making a full spreadsheet UI, I'm working on support for cell numbers and ranges in formulas (so others can do so).
<$tiddler tiddler="$:/temp/SvgSlider">
<$edit-text tag=Input field=val type=range class=longslider/>
<svg viewBox="-100 -100 200 200" width=400 height=400>
<circle cx=0 cy=0 r=<<formula "100*{{!!val}}%">> style="fill:black;"/>
<circle cx=0 cy=0 r=<<formula "100*{{!!val}}%^3">> style="fill:red;"/>
<circle cx=0 cy=0 r=<<formula "100*{{!!val}}%^4">> style="fill:white;"/>
<$list filter=".1 .2 .3 .4 .5 .6 .7 .8 .9 1" variable=rad>
<$list filter="0 1 2 3 4 5 6 7 8" variable=ori>
<circle
cx=<<formula "<<rad>>*100*{{!!val}}%^1.2*sin(pi*<<ori>>/4.5+{{!!val}}*.08+<<rad>>)">>
cy=<<formula "<<rad>>*100*{{!!val}}%^1.2*cos(pi*<<ori>>/4.5+{{!!val}}*.06+<<rad>>+.5)">>
r=<<formula "5*{{!!val}}%^1.5">> style="fill:white;"/>
</$list>
</$list>
</svg>
</$tiddler>
I shall check this out! Cheers.
... this does make some sense for the record.
... <$for x="0,100"> widget to make it easier to iterate over a series of numbers. (I was also thinking about how useful it would be to have a timer widget, which either fires events at an interval or advances a state tiddler's numeric value over a period of time...
... timer widget .... This would be sufficient to implement animations, simulations and self-organizing maps.)
As a conversation piece, here's a quick experiment in SVG animation
Question: do you have or are you planning any rounding or averaging functions?
I did find that the rounding functions fail when a second parameter is provided, so I submitted an issue on Github.
I am very interested in "Multidimensional" arrays.
One question: Could this be made to work with date and time?
Reverse polish notation https://tid.li/tw5/hacks.html
Is there value sharing what I find, or do you have it covered?
May I ask how you use the results TRUE and FALSE in wikitest once calculated?
if({{!!x}}<1, "x is less than 1", "x is more than 1")
ifs(and({{!!x}} > {{!!y}}, {{!!x}} > {{!!z}}), "x is biggest", ({{!!y}} > {{!!z}}), "y is biggest", TRUE, "z is biggest");
if(and({{!!x}} > {{!!y}}, {{!!x}} > {{!!z}}), "x is biggest", if({{!!y}} > {{!!z}}, "y is biggest", "z is biggest"));
What appears missing that I need at the moment is; Add_month, Add_year
`ValueError: TypeError: value.asString is not a function value: 20180101001411129`
Just to make sure it is intentional - concatenation: 1 & 2 = 1.002.00 (...i.e 1.00 and 2.00)
Apropos binary - additional feature idea: I occasionally want to convert between number bases... hex, dec, binary etc.
Date Description Cost
01/12/17 Hair cut 12.00
07/12/17 Buy Squirrel 45.00
10/12/17 Innoculate Badger 14.44
TOTAL: 71.44
DAILY AVERAGE SPEND (December): 2.30
(2) Quite important. Can I in the interface just add a line? That would make for basic accounting bliss.
Evan, I find it confusing that2+3*4 > 12 works but not "2+3*4 = 12" nor "2+3*4 == 12" .And why does (= pow(3, 2) =) work but not (= gr(3, 2) =) ?
(1) Can I create a table like this that auto gives the results?...
(2) Quite important. Can I in the interface just add a line? That would make for basic accounting bliss.
<!-- note: we want dates in this format, and numbers displayed with two digits after the decimal point. -->
<$vars formulaDateFormat="DD/mmm/YYYY" formulaFixed="2">
<table>
<!-- This first row is the table header. -->
<tr>
<th>Date</th>
<th>Description</th>
<th>Cost</th>
</tr>
<!-- This $list widget will show each of our expenses. -->
<$list filter="[prefix[Demo]tag[Expense]]">
<tr>
<td> <$link>(= {{!!date}} =)</$link> </td>
<td> {{!!summary}} </td>
<td> {{!!cost}} </td>
</tr>
</$list>
<!-- This row calculates a total. -->
<tr>
<td colspan="3"> <hr/> </td>
</tr>
<!-- This row calculates a total using SUM. -->
<tr>
<th> </th>
<th> TOTAL: </th>
<th>
(= sum([prefix[Demo]tag[Expense]get[cost]]) =)
</th>
</tr>
<!-- This row shows our average per day. This is a bit more complex! -->
<tr>
<td> </td>
<td> Average per day (December): </td>
<td> (= sum([prefix[Demo]tag[Expense]get[cost]]) / 31 =) </td>
</tr>
</table>
</$vars>
Please continue experimenting and reporting any issues you turn up. I'll be interested to see if the date & time stuff suits the needs of the users who've chimed in about that.
Deleted (see correction below)
1.) Apparently, a date from a tiddler field is accepted only when it is formatted as "YYYYMMDD" (but not e.g. "YYYY-MM-DD"). Maybe you could add this info to the documentation?
2.) I created a group of tiddlers with the same tag. (...) Using the "sum" function here is a bit clumsy, though.
Hi,
On Monday, December 18, 2017 at 12:14:02 AM UTC+1, Evan Balster wrote:Please continue experimenting and reporting any issues you turn up. I'll be interested to see if the date & time stuff suits the needs of the users who've chimed in about that.Very cool! Thank you!
Two quick observations:
1.) Apparently, a date from a tiddler field is accepted only when it is formatted as "YYYYMMDD" (but not e.g. "YYYY-MM-DD"). Maybe you could add this info to the documentation?2.) I created a group of tiddlers with the same tag. Each tiddler contains a date in the "datum" field. I was able to pick the latest date from the list and add 14 days with the following syntax:
(= date(sum([tag<currentTiddler>!sort[]last[1]get[datum]],14)) =)
2.) I created a group of tiddlers with the same tag. Each tiddler contains a date in the "datum" field. I was able to pick the latest date from the list and add 14 days with the following syntax:
(= date(sum([tag<currentTiddler>sort[datum]last[1]get[datum]],14)) =)
(= nth([tag[Expenses]], 3)
=)
= Ten-Sodas
Wohooo!
Getting greedy but... possible to make array output be links? I tried this but no worky:
(= "[[" & nth([tag[Expenses]], 1) & "]]" =)
(= arraystring([tag[Expenses]], "[[", "]] [[", "]]")
Released version 0.1.2: http://evanbalster.com/tiddlywiki/formulas.html
* Fix an off-by-one-month error parsing transcluded date fields in YYYY-MM-DD format
(= year(date(20180314)) =)-(= month(date(20180314)) =)-(= day(date(20180314)) =)
Thanks again for all your hard work. With a plugin of this complexity, Im wondering if there should be "unit tests" tiddler that could keep track of the various corner cases proposed here and that you also identify.
However, the "month" function still seems to be off by one month (please note that I used version 0.13).
Whoops! That's some JavaScript leaking through. Patched in git, hotfix attached.
Released version 0.1.2: http://evanbalster.com/tiddlywiki/formulas.html
...
t
, value
, textjoin
len
, exact
, mid
, substitute
, split
, trim
regexreplace
, regexmatch
, regexextract
, regexextract1
.julian
, to_julian
month
functionif
function, disable if
function pending support for more powerful function constructioncount
and counta
functions.Evan,
Please forgive my Ignorance; What can a and b be equal to in Formulas' logical functions, like IF and IFS?
I am thinking if something evaluates to true how do I use this to
- list
- transclude
- Use macro
- Show some text etc...
- Set a variable/field
I imagine there is a way to write a list filter if a formula it true to show when true (or False) etc...
I expect knowing this may help the less sophisticated users (still me at this point) make use of formula.
Thanks in Advance
Tony
IF( gt([all[tiddlers]get[modified]], add_days(date(now()),-5)), <<title>> + "has been recently modified")
Recently modified:
<$list filter="[all[tiddlers]]">
(= if(days(tw_date({{!!modified}}), now())<2, {{!!title}}&", ", "") =)
</$list>
(= IF(count([some-filter-that-grabs-the-fields]) > 0, "<hr/>", "") =)
Hello, all —I got fed up with the lack of good number-crunching capabilities in TiddlyWiki, and after griping about it for a year I fixed it.Introducing the Formula plugin: http://evanbalster.com/tiddlywiki/formulas.html (currently version 0.1.2)
<!-- Set a range from 1 to the number of items -->
<$formula-vars indexRange=" '1,' & count([myFilter]) ">
<!-- Go through the range... -->
<$list variable="index" filter="[range< indexRange >]">
<!-- Get the Nth element from the filter... -->
<$list filter="[myFilter] +[nth<index>]">
#<<index> = {{!!title}}
</$list>
</$list>
</$formula-vars>
<$button>Apply Unique Ledger Numers
<!-- Set a range from 1 to the number of items -->
<$formula-vars indexRange=" '1,' & count([myFilter]) ">
<!-- Go through the range... -->
<$list variable="index" filter="[range< indexRange >]">
<!-- Get the Nth element from the filter... -->
<$list filter="[myFilter] +[nth<index>
]">
<$action-setfield ledger-number=<<index>>/>
</$list>
</$list>
</$formula-vars>
</$button>
In the future, Formulas should include some ability to go through arrays and apply a function to each item inside them, which would form a more efficient solution than the one here (which will scale up poorly because it runs myFilter once for each element in the list).
Last year I wrote a filter operator plugin called addposition that can be used to solve this same problem more efficiently.
+
and -
(these break precedence rules).\\
, \'
, \"
, \n
, \r
, \t
, \v
, \f
, \b
, \0
, \u1234
(unicode)is_leap_year(y)
, days_in_year(y)
, days_in_month(y,m)
gcd
and lcm
(?igm)
flags in regular expression strings.regexextract
and regexreplace
search globally by default.regexmatch
and regexextract1
search non-globally by default.if
The Get your Plugin indicates the plugin is Version 0.1.0 although it is now 0.1.6
fract
, modulo
/mod
, atan2
, clamp
, mix
, step
, smoothstep
regexextract
and regexextract1
Functions.regexextract("cats, red cats, and blue cats", "([a-z]+) cats", 1)
results in red
and blue
.$noRefresh
option in FormulaVarsWidget.<td colspan=(= 2+2 =)/>
\define showtodayrange(datefield1,datefield2)
<progress
value=(= days( date( {{!!$datefield1$}} ) , now() ) =)
max=(= days( date( {{!!$datefield1$}} ) , date( {{!!$datefield2$}} )) =)/>
\end
\define showtodayrange(datefield1,datefield2)
<progress
value=<<formula "days( date( {{!!$datefield1$}} ) , now() )">>
max=<<formula "days( date( {{!!$datefield1$}} ) , date( {{!!$datefield2$}} ))">>/>
\end
Last year I wrote a filter operator plugin called <a href="https://groups.google.com/forum/#!topic/tiddlywiki/13_TTJqEEiw" rel="nofollow" target="_blank" onmousedown="this.href='https://groups.google.com/forum/#!topic/tiddlywiki/13_TTJqEEiw';return t
On Friday, 22 December 2017 14:16:09 UTC-6, coda coder wrote:<blockquote class="gmail_quote" style="margin:0;
I've considered allowing the shorter <single-bracket> style anywhere in formulas, and there isn't much stopping me on a technical level, but I worry that supporting two styles might create more confusion than it's worth.
Better to stay similar to WikiText, in my mind...
The latest version of Formula has some implementation errors in the modulo, trim and subtitute functions. These have been found and patched, but the change isn't yet released, as I'm working on some major enhancements for release today or tomorrow.
(= sum(1.5,1.2,2,0.9) =)
(= 2+1.2+0.9+1.5 =)
I get 5.6000000000000005 as a result (instead of 5.6).
A substantial re-write of the formulas plugin that introduces various improvements and improves support for functional programming. Various minor compatibility-breaking changes were made.
let
construct for making local variables.function
declaration. Closures are not supported yet.map
function for manipulating array elements.precision
(no value).$formula-vars
will display any errors instead of its normal content.$formula
uses tc-error
styling.sum
, average
, product
and count
.count
ignores empty values.counta
counts empty values.$noRebuild
option is not called $noRefresh
substitute
and trim
functions now process all occurrences, not just one.modulo
function.%
operator no longer affects display style.+
, -
, add
and subtract
no longer auto-sum their operands.sum
instead.