Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi
Tinderbox Users >> Agent, Actions, Rules & Automation >> Collect keyattributes and count if populated
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi?num=1351689939

Message started by Gernot on Oct 31st, 2012, 9:25am

Title: Collect keyattributes and count if populated
Post by Gernot on Oct 31st, 2012, 9:25am

Dear all,

a little bit of procrastination before NaNoWrimo starts and having a good excuse during November to code in tinderbox instead writing and trying to achieve my daily word target.

I have created a tinderbox to plot out my storyline and have defined prototypes for scenes and sequels.  Each prototype contains a couple of mandatory and optional keyattributes (story question, keywords, conflict, location, point of view ..) to make the writing process easier. I first have plotted roundabout 50 scenes and sequels by just giving it a name with out filling further keyattributes.

I was trying now to define a rule, action (?) to collect all keyattributes of a scene or a sequel and check if every keyattribute has been populated. If so I would like to count and store the result for each scene in another attribute.

e.g.
Scene has 10 keyattributes, 7 keyattributes has been populated, 3 keyattributes are empty. Completeness attribute would show 70% complete or 30% missing.

I tried different things:
1. Check if populated increment by one
Didn't work has the check is done with every update and is quite cumbersome considering I need to define 1 if clause for each keyattribute and having only the small edit field for rules.
2. Boolean check on keyattribute content and sum return values.
Didn't work as if-check returns only TRUE and FALS but not 1 or 0.

Is there any easy/better way to get this done? Thanks for pointing me in the right direction.

Brgds,
Gernot




Title: Re: Collect keyattributes and count if populated
Post by Mark Bernstein on Oct 31st, 2012, 9:44am

To check whether a string attribute has been populated, simply check whether it's empty or not:

    $MyString != ""

If you'd like to make a set of all the notes that have a specific value, try

    find($MyString=="Belinda" )

If you just want to know how many notes are about Belinda

    find($MyString=="Belinda" )

If you want to know what values have been used for $MyString

   values($MyString)



Title: Re: Collect keyattributes and count if populated
Post by Mark Anderson on Oct 31st, 2012, 12:18pm

List.each() looping to the rescue! You scene note (or prototype for scene notes) want this as, or added to, its $Rule:


Code:
$CompleteState=0;
$KeyAttributes.each(X) {
     if(eval("$"+X)) {      
           $CompleteState = $CompleteState + 1;
     }
};
$Pattern="bar($CompleteState,0,$KeyAttributes.size)";

To use the above, you also need to add a Number-type user attribute called "CompleteState".

The loop takes each item in $KeyAttributes, which is an attribute without a $-prefix, turns it into an attribute $-reference and then does a short-form attribute evaluation to get a true/false result as to that attribute's completion. On completion of the loop, each attribute's completion state is test.

The latter is perhaps an over simplification as the test is whether the attribute is in non-default state. If you need a different test for 'completion' of the attribute then you will need to code a test for each attribute.

The $Pattern bit is a for Map view use.  It will show a progress bar on the notes map icon giving a visual indication of completeness. As the latter is always stored in $CompleteState, you can leave the $Pattern code out from the Scene note and use it on a dashboard elsewhere in the TBX.

Unwittingly, your scenario needs one of the more complex things action code can do. So do ask if stuck or it simply doesn't make sense.

If you don't want to check all key attributes, make a new Set attribute called $MandatoryAttributes and copy to it from $KeyAttributes only those attributes whose completion you wish to check.  Amend the code example above to use $MandatoryAttributes.

Title: Re: Collect keyattributes and count if populated
Post by Gernot on Oct 31st, 2012, 12:49pm

Thanks Mark for the prompt reply.

It works perfectly. Just added


Code:
$CompleteState =(($CompleteState-13)/13).format(2);


to store the value as percent.

Btw, is there any way to increase the size of the action code window? Or what might be a good workaround to edit more complex scripts as provided in your post below (Linked action code files?).

Thx, Gernot

Title: Re: Collect keyattributes and count if populated
Post by Mark Anderson on Oct 31st, 2012, 1:19pm

I'm assuming 13 is the number of items in $KeyAttributes (or my alternate suggestion above of $ManadatoryAttributes). If so might consider:


Code:
$CompleteState =(($CompleteState-$KeyAttributes.size)/$KeyAttributes.size).format(2);


Otherwise, is you alter your key attributes later (up or down in number) your percentage figure will be incorrect. With a List or set, .size gives you the number of discrete items in the list.  With a String it gives you the number of characters in the string.

Too much code for an edit box.  Indeed - that's why i used the code note concept.  In making the demo I did this:
  • Added a new Number attribute $CompleteState.
  • Added the built-in prototype "Code" (via File menu).
  • Added a prototype note "PScene" and set a number of specimen attributes as key attributes.
  • Added a root level container "codes" with an OnAdd to set new childresn to sue the "code" prototype.
  • Added a child to "codes" called "cKA_Complete". The $Text of this note is where the rule code you see was developed.  The note's Rule was set to: $Rule("pScene") = $Text. This means that every time the note's rule fires it copies its current $Text as the $Rule in the "pScene" prototype. Scene note(s) using the prototype then inherit the rule. Using a note configured for coding is much easier for complex stuff than fiddling the boxed on a rename dialog. It even allows for space/tab whitespacing and indenting of code without affecting how it runs.
  • As intimated, the main rule lives in the prototype for Scenes and is then applied via inheritance to individual scene notes.
OK, yes, this more set-up than just cramming code into an input box on rename, but once you're past trivial code you do need a little more prep. However, if you bother to set up a few prototypes you can get massive leverage for your changes. The 'code' note concept used above is discussed here.

Title: Re: Collect keyattributes and count if populated
Post by Mark Anderson on Oct 31st, 2012, 2:46pm

Looking at the percentage calculation (and my reworking of it), it actually gives to a negative version of the amount left to complete.  IOW, if there are 4 items and 3 are complete you get '-0.25'. I suspect what's really wanted is '0.75' or, for bar() pattern use, '75'. To get a '0.75.' type figure, here are both codes reworked:


Code:
$CompleteState =($CompleteState/13).format(2);

$CompleteState =($CompleteState/$KeyAttributes.size).format(2);


[edit]code above updated to reflect better suggestion in next post below[/edit]

To use with bar(value), where using the single parameter version it expects a value beween 0-100, you'd use:


Code:
$Pattern="bar($CompleteState*100)"


This will convert a '0.75' output from the first code into a '75', i.e. 75%, parameter for use in bar().

A benefit of the complete state being sorted as a decimal fraction is you can then do dashboard-y type thinks like find the number of scenes where completion state is less than 60% ($CompleteState<0.6)  and so on.

Title: Re: Collect keyattributes and count if populated
Post by Gernot on Oct 31st, 2012, 3:45pm

Thanks Mark again, very helpful. I already checked it. The below works also fine for me.


Code:
$CompleteState =($CompleteState/$KeyAttributes.size).format(2);  


e.g. 2/13 where 2 are the completed attribs and 13 the number of attribs.

I think I am now pretty well prepared for NaNo ;o) and just realized that I only have completed 40% of all scenes. Luckily the first act has at least 60%. So, still some work to do.

The workaround for the code box I will definitely try. Sounds good if I can have the code inside the text of the prototype. Some procrastination for time in November where I don't want to write anymore.

@all, going to share the tbx soon, so somebody can use it at least for the NaNo13 and will call it "Scene Plotter" as I have already shared "Essay Plotter" and "Story Plotter". http://textnotes.wordpress.com/2012/07/03/essay-plotter/

Thank you for the support, much appreciated.

Brgds,
Gernot

Title: Re: Collect keyattributes and count if populated
Post by Mark Anderson on Nov 1st, 2012, 5:18am

I've done a worked tutorial on this topic. See more in this thread. I figured it might help some others getting into NaNoWriMo.

Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com) » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.