Random numbers in fET

84 views
Skip to first unread message

whatever

unread,
Feb 18, 2011, 1:15:30 PM2/18/11
to TiddlyWiki
Hi!

I need a little help with javascript.
I'm trying to create a sort of Did You Know function, like Wikipedia
has. For that, each "article" tiddler has a Quotation part in it. What
I want is to display random 10 Quotations from the last 50 modified
articles.

My fET looks like this:
<<forEachTiddler
where 'tiddler.tags.contains("article")'
sortBy 'tiddler.modified' ascending
write '(index == RandomIndex) ? "*...that <<tiddler [["+tiddler.title
+"/Quotation]]'>>?" : ""'>>

I also found a script that finds random x numbers from among y
numbers.

<script>
var Found = false;
var Current = new Array();
var MaxValue = 50; //(Example 2 is equal to: 0,1,2)
var NumUnique = 10; //The number of unique numbers required
var Count = 0;
var Current = new Array(NumUnique);
GetUnique()
var i;
var u;
for (u=0; u<NumUnique; u++) {
document.write(Current[u]+"<br/>");
}
function GetUnique()
{
for (i=0;Count<NumUnique;Count++)
{
Found=false
var rndValue = get_random()
var j=0
for (j=0;j<Current.length;j++)
{
if (Current[j] == rndValue)
{
Found=true
break
}
}
if (Found)
{
Count--
} else {
Current[Count]=rndValue
}
}
}
function get_random()
{
var ranNum= Math.round(Math.random()*MaxValue);
return ranNum;
}
</script>

The problem is, I don't know how to incorporate the script into the
fET where RandomIndex is at the moment. Or vice versa maybe. Any help
would be appreciated.

w
Message has been deleted

Tobias Beer

unread,
Feb 18, 2011, 2:39:14 PM2/18/11
to TiddlyWiki
Hi whatever,

Things could be rather simple if fET were not (always) the tool of
choice.

<script>
var a=[],i,max=10,n=0,out='',t,tags,
tids=store.getTiddlers("modified","excludeLists");
for (t in tids) {
tags=tids[t].tags;
if (tags&&tags.contains('$1'))a.pushUnique(tids[t].title,true);
}

while(n<max&&a.length>0){
n++;
i=Math.floor(Math.random()*a.length);
out+="*[["+a[i]+"]]\n";
a.splice(i,1);
}

return out;
</script>

Simply put this into a tiddler, call it "random10" and then use the
tiddler macro like this...

<<tiddler random10 with: article>>

Cheers, Tobias.

Måns

unread,
Feb 18, 2011, 2:48:41 PM2/18/11
to tiddl...@googlegroups.com
Hi Tobias & Whatever


Things could be rather simple if fET were not (always) the tool of
choice.

I know how to change a fET to output a custom field ie. "name".. instead of tiddlertitle.
How would I do that in this script?:
 
<script>
var a=[],i,max=10,n=0,out='',t,tags,
  tids=store.getTiddlers("modified","excludeLists");
for (t in tids) {
  tags=tids[t].tags;
  if (tags&&tags.contains('$1'))a.pushUnique(tids[t].title,true);
}

while(n<max&&a.length>0){
  n++;
  i=Math.floor(Math.random()*a.length);
  out+="*[["+a[i]+"]]\n";
  a.splice(i,1);
}

return out;
</script>

Cheers Måns Mårtensson 

whatever

unread,
Feb 18, 2011, 3:08:03 PM2/18/11
to TiddlyWiki
Hi, Tobias.
I use fET, because it usually solves all of my problems. :D Anyway, I
don't want to display tiddler titles but specific parts or sections or
slices in those tiddlers. Displaying the last 10 is no problem, I
already did that with fET, what I was looking for was random 10 from
the last 50.

w

Tobias Beer

unread,
Feb 18, 2011, 4:03:59 PM2/18/11
to TiddlyWiki
Hi again, whatever...

Well, you're right, I overlooked those 50... but that's no biggie :-)

<script>
var a=[],i=0,num=10,max=50,n=0,out='',t,tags,x,
tpl="*[[%0]]\n",
tids=store.getTiddlers("modified","excludeLists");
for (t in tids) {
i++;
tags=tids[t].tags;
if (tags&&tags.contains('$1'))a.pushUnique(tids[t],true);
if(i>max)break;
}

while(n<num&&a.length>0){
n++;
i=Math.floor(Math.random()*a.length);
x=a[i].title;
out+=tpl.format([x]);
a.splice(i,1);
}

return out;
</script>


Btw, in case you thought otherwise ...it did retrieve 10 random ones.

I have also added a variable called tpl which lets you specify your
output format. Of course that wont allow you to output anything other
than the tiddlers title. However, if you want to get anything else,
you would have to take the article tiddler referenced via a[i] and
assign the data you want from it to the variable x, for example. If
you need more than one piece of information, add another variable,
maybe y and assign the desired value to it. Then add it to the
tpl.format([]) instruction like this:

//get the title
x=a[i].title;
//get the tags
y=a[i].tags;
//output both
out+=tpl.format([x,y]);

...and so, unless undefined, you also display the tiddlers tags as a
comma separated list. For that, you would also want to change the
template variable "tpl" to output two pieces of information, maybe...

tpl="*[[%0]] (tags: %1)\n"

...whereas %0 would be replaced with the tiddlers title and %1 with
its tags.


As for your question Mans. You would have to change the script as
well. Maybe define the template variable like so...

tpl="*[[%0]] -> fieldX: %1\n"

...and then get the field value from the tiddler object and format
your template accordingly...

//get the title
x=a[i].title;
//get the field value for tiddler a[i]
var f=store.getValue(a[i], "fieldx");
//output both
out+=tpl.format([x,y]);


Cheers, Tobias.

Tobias Beer

unread,
Feb 18, 2011, 4:38:35 PM2/18/11
to TiddlyWiki
Hi whatever,

A simpler answer might have been... fET is not made such reiterative
loops. Hence, you need a script, macro or plugin which does that for
you.

Cheers, Tobias.

whatever

unread,
Feb 18, 2011, 5:11:06 PM2/18/11
to TiddlyWiki
Hi, Tobias.
I tried the new version, however, it seems that "if(i>max)break;"
breaks it. When I hid this line, it displayed the titles.
Also, even when I used num=1,max=2, it ignored the date modified.
I also tried:
x=a[i].title;
y=a[i].tags;
out+=tpl.format([x,y]);
but it didn't work.
And what I need is to display the content of parts or slices or
sections, not fields.

w

Tobias Beer

unread,
Feb 19, 2011, 8:25:07 AM2/19/11
to TiddlyWiki
Hello w,

You're right, there was a bug with a control variable in one of the
loops. I have posted the thing now as a script on my tiddlyspace [1].
It now allows you to output one (!) section, slice or field per output
tiddler, wrapped in a template you can customize.

Let me know if that works for you. I might possibly turn that thing
into a macro with more flexible templating options.

Cheers, Tobias.

[1] http://tobibeer.tiddlyspace.com/#%5B%5BScript%3A%20GetRandomTids%5D%5D

Tobias Beer

unread,
Feb 19, 2011, 9:05:13 AM2/19/11
to TiddlyWiki
Just to correct the last code posted here ...and to give you an
alternative "single purpose script" as opposed to the generalization
[1] you can find an example for what I think you might have had in
mind here...

http://pastebin.com/gBwn1R5U

whatever

unread,
Feb 19, 2011, 2:16:20 PM2/19/11
to TiddlyWiki
Hi, Tobias.
First, thanks for all the help. :D
Anyway, I tried the script on pastebin (1) and modified the output so
that I now get what I want. However, the random function still doesn't
work quite right. I mean, yes, it does randomize the output, but it
chooses from among all the articles. I tried limiting to num=1,max=2,
but as I refreshed, the script didn't just cycle between the last two
modified but among all the articles. Which, as I think about it, isn't
that bad, but I still wanted to let you know.

(1) http://pastebin.com/gBwn1R5U

Tobias Beer

unread,
Feb 19, 2011, 3:45:47 PM2/19/11
to TiddlyWiki
Ouch, sorry...

It's good that you point it out.

1) One of the errors is something that I had fixed in the version
posted on my tiddlyspace, yet forgot to correct in the one called
"single purpose script". So actually, my last version gave you random
tiddlers, but from the wrong end :-D

2) However there was another error in the break condition which
resulted in the script taking one tiddler too many.

Grab the corrected version from here...

http://pastebin.com/nXjn09g6

Cheers, Tobias.

whatever

unread,
Feb 19, 2011, 5:19:32 PM2/19/11
to TiddlyWiki
Hi!
I tested the new version. It works as advertised, but there is an
interesting thing I noticed. When max=4, it takes the last 4 modified
articles, but as soon as max=5 or more, it takes the last 5 (or more)
+1 articles. No biggie, just interesting. :)

w

whatever

unread,
Feb 19, 2011, 6:20:00 PM2/19/11
to TiddlyWiki
Hi! Again. :)
I noticed another thing. If the article doesn't contain the defined
section and still gets randomly chosen, the display is weird. For
example, one of my outputs is:
tpl="*... that %0?\n",
and the result for an article that doesn't contain the defined section
is:
* ... that ?
The script basically presupposes that each article contains that
section. One way around is to add a tag to each article which contains
the defined section and then have the script parse only those
articles. Just thought I'd share.

w
Message has been deleted

Tobias Beer

unread,
Feb 20, 2011, 6:07:10 AM2/20/11
to TiddlyWiki
Hi again w,

As for taking one too many once we're on 5+, I have no clue why that
would happen for you... can't reproduce it.

I've added a new variable called "req" in the single purpose script or
parameter called "required" on the version on my TiddlySpace which
allows you to only take tiddlers into account that actually provide
the section, slice or field.

Get the new version of the single purpose script from here:

http://pastebin.com/zTYbeSQ9

...or the wee more generic version from my TiddlySpace:

http://tobibeer.tiddlyspace.com/#%5B%5BScript%3A%20GetRandomTids%5D%5D

Cheers, Tobias.
Message has been deleted

Tobias Beer

unread,
Feb 20, 2011, 7:25:37 AM2/20/11
to TiddlyWiki
As suggested earlier, I eventually turned the script into a macro
which runs on its own w/o InlineJavascriptPlugin.

http://tobibeer.tiddlyspace.com/#RandomTiddlers

Cheers, Tobias.

whatever

unread,
Feb 20, 2011, 8:18:34 AM2/20/11
to TiddlyWiki
Thanks, Tobias, you rock! :D
As for the 5+ thing, it occurs with the last version as well. It's not
a problem, since one less or more doesn't matter, it's just curious as
hell.
w

Tobias Beer

unread,
Feb 20, 2011, 9:14:03 AM2/20/11
to TiddlyWiki
Hi w,

As for the file you've send me...

For one, I would _not_ recommend using PartTiddlerPlugin anymore as
you can use hidden sections, like so

/%
!Hidden Section A
Some content
!Hidden Section B
More content
!End
%/

Then you can use transclusion to fetch the contents...

<<tiddler "SomeTiddler##Hidden Section A">>

...or - assuming that "tid" is a valid tiddler object - you can use
the following javascipt to fetch the contents:

store.getTiddlerText(tid.title+'##Hidden Section A');

Although the output templates in your tiddler GetRandomTidsShort are
not filled with any data, it seems to give the right output when I
use:

out+=tpl.format([a[i].title]);

It also seems that you cannot fetch the contents of a "part" via...

store.getTiddlerText(tid.title+'/HiddenPartName');

One final bit of advise... I would turn off AutoSave via zzConfig on a
2MB file.

Cheers, Tobias.

whatever

unread,
Feb 20, 2011, 9:44:30 AM2/20/11
to TiddlyWiki
Hi!
I use PartTiddlerPlugin (1), because you can do this:
bla bla bla <part PartName>some text</part> blah blah...

You can't do this with hidden sections, as far as I know. Also, when
using DcTableOfContentsPlugin (2) or SectionLinksPlugin (3), it
doesn't require curly brackets to hide it from ToC. Eric explained the
use of hidden sections in another thread (4), so I'm familiar with
that.

And yes, you can call up parts via
store.getTiddlerText(tid.title+'/HiddenPartName');

See GetRandomTidsShort (4), the other examples are older and have not
been deleted yet.
The whole default text of the New Tiddlers is a part simply called "1"
and the output is correctly:
•... that Type the text for 'New Tiddler (3)'? Read more ...
and so on.

w

(1) http://tiddlywiki.abego-software.de/#PartTiddlerPlugin
(2) http://devpad.tiddlyspot.com/#DcTableOfContentsPlugin
(3) http://www.TiddlyTools.com/#SectionLinksPlugin
(4) http://groups.google.com/group/tiddlywiki/browse_thread/thread/be2c48729f148b65

Tobias Beer

unread,
Feb 20, 2011, 1:09:37 PM2/20/11
to TiddlyWiki
Hi w,

1) In what circumstance would you benefit from or even depend on
"inline parts"?

2) Unless you have some extension to PartTiddlerPlugin that I am
missing, the following does not (!) yield the desired output:

store.getTiddlerText('SomeTiddler/SomePart')

Instead you have to do something like this:

t=store.fetchTiddler('SomeTiddler/SomePart');
t=t?t.text:'';

3) I have added this and fixed the bug from the macro in the "single
purpose script" and posted an update here:

http://pastebin.com/z4rXNBv3

4) As for the combination of DcTableOfContentsPlugin or
SectionLinksPlugin and hidden sections ...it seems to me their
behaviour is faulty while the core probably doesn't provide adequate
utility functions.

Cheers, Tobias.

whatever

unread,
Feb 20, 2011, 2:06:17 PM2/20/11
to TiddlyWiki
Hi!
1. Inline parts come in hand especially in cases like mine, when I can
simply insert the part in the middle of the text. It does not corrupt
the flow of the text and I can reference that part, like in my Did You
Know feature. Also, when you have multilined text and you need to use
it in a table. You put the text in a hidden part and then transclude
it in a table cell. Parts don't need to be hidden, by the way.

2. In your script there is this line
v=store.getTiddlerText(tids[t].title+'##Summary');
which I've changed into
v=store.getTiddlerText(tids[t].title+'/1');

It works fine.

3. And after checking the new version, I noticed that that is in your
new script as well, beside some other minor changes. I also noticed
that random numbers appear to be unique this time.

4. That, I'm afraid, way over my head. :)

w

whatever

unread,
Feb 26, 2011, 12:39:04 PM2/26/11
to TiddlyWiki
Hi!
After playing with the script a bit, it occurred to me that it is
limited to a single occurrence of a particular section/slice/part. But
suppose you had several of them, sequentially numbered, like: Slice1,
Slice2, Slice3... Could it be possible that when a random article
containing the keyword (in this example Slice) is selected, that the
script would count the number of appearances of that keyword and then
select a random one?

I tried adding the following:
Instead of v=store.getTiddlerText(tids[t].title+'##Summary')

I added three more lines and modified the original line:
var txt=store.getTiddlerText(tids[t].title);
var s = txt.match('Summary').length;
j=Math.floor(Math.random()*s);
v=store.getTiddlerText(tids[t].title+'##Summary'+j);

It didn't quite work. Any ideas?
w
Reply all
Reply to author
Forward
0 new messages