Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
Tinderbox Users >> Questions and Answers >> Odd question on truncated $DisplayExpression

Message started by J Fallows on Apr 18th, 2016, 12:08am

Title: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 12:08am

In an Outline view, I want to number the items. Thus I have set a rule in a prototype:
  $DisplayExpression=$SiblingOrder + ". " + $Name

The unexpected aspect of this affects the items in which $Name includes a comma or a colon. With the rule applied, the displayed name stops at that punctuation mark. Eg:

   Bader, influence of Xi Jinping on military policy
   Christensen: South China Sea showdown is dangerous

  1. Bader
  2. Christensen

How do I set the rule to display a $SiblingOrder number, but also the whole $Name as was displayed before? Thanks

Title: Re: Odd question on truncated $DisplayExpression
Post by Scott Heftler on Apr 18th, 2016, 12:23am

The trick I've always used is to escape the whole $DisplayExpression by adding "'" and "'" at the beginning and end, like so:

$DisplayExpression="'" + $SiblingOrder + ". " + $Name + "'"

How does that work?

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 12:29am

How does that work?

Perfectly! Thank you very much. I had not thought of that, but now I know. Really appreciate it.

Title: Re: Odd question on truncated $DisplayExpression
Post by Mark Anderson on Apr 18th, 2016, 3:46am

For later readers still unclear as to the issue here, the underlying reason is plain if you follow JF's first post and then inspect the resulting $DisplayExpression of added items via the inspector. You probably expect to see action code there, but instead you see a string with the output of the desired $DE? The first example's $DE is:

  1. Bader, influence of Xi Jinping on military policy

One assumes Tinderbox is making a best guess as to where to clip a potentially long string. On my system a clip occurs at a comma but not at a colon (JF's second example note title). However, what we expected to see in the $DE code box was this:

  $DisplayExpression=$SiblingOrder + ". " + $Name

Scott's answer fixes the clipping of the title, but looking in the $DE box the 'code' is now like this (again for the first example note):

  '1. Bader, influence of Xi Jinping on military policy'

The $DE works insofar as the full string shows, but if the note title ($Name) is edited, the Display Expression won't be.

The underlying  problem is how one uses one attribute ($OnAdd) to set unevaluated code in another attribute. The answer is surprisingly simple - you place matched quotes around the whole code string. As the desired code requires double-quotes in it, the outer quotes need to be single.

$OnAdd code:

  $DisplayExpression = '$SiblingOrder + ". " + $Name'

Resulting $DisplayExpression code:

  $SiblingOrder + ". " + $Name

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 8:09am

$OnAdd code:

 $DisplayExpression = '$SiblingOrder + ". " + $Name'

Resulting $DisplayExpression code:

 $SiblingOrder + ". " + $Name

Mark A, thanks for the additional explanation, clarifying as always.

Followup: because I wanted the displayed name to be updated if I edited $Name itself, I had put this code in a Rule, not an on-add Action. Is any of your explanation different if we assume we're talking about a Rule?

In practical terms, the setup now works from my POV, with single quotes around the whole thing ('$SiblingOrder + ". " + $Name'). Just wanting to be sure I understand the larger picture.

Title: Re: Odd question on truncated $DisplayExpression
Post by Mark Anderson on Apr 18th, 2016, 8:48am

Err, no. Action, rule or edict, your error quite unintentionally was to set $DE to the output of some action code, rather than to the actual action code. Only in the latter case does the $DisplayName get calculated on the fly from the referenced attribute(s).

Thus if the $DE is correct as per my last post, changing $Name will result in the $DE evaluating to give an updated $DisplayName.

For later readers it's worth making the point that if your $DE involves a lot of calculation (or even lots of '+' joins), consider a rule or edict to store the calculated [cis] values. Then the $DE is just set to the attribute name of the attribute storing that value. This can free up resources for Tinderbox to get on with other tasks.  It's not a problem with 10 notes, but if you've a 1,000 all with complex $DE, that is the point to start factoring this element.

I hope that helps = I hope i've answered the right question.  :)

Title: A better way to set display expressions
Post by Mark Bernstein on Apr 18th, 2016, 12:36pm

If you are setting display expressions with a rule or an action

     $DisplayExpression = $someAttribute"+"...some string"+"$Name"
you are complicating your life unnecessarily.  Instead, do this:

1) Make a note somewhere, and using the Inspector, set its DisplayExpression.  Adjust it until it does what you expect.  This is much simpler than writing a rule!

     $someAttribute + "..some string.." +$Name

2 replace your complicated rule with the much simpler

     $DisplayExpression = $DisplayExpression(/path/to/example)

I frequently have a top-level container named "configuration" that can hold notes like this.  This has a bonus of making your intention much clearer.

     Rule: $DisplayExpression=$DisplayExpression(/configuration/race results)

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 12:57pm

Mark A, thanks for the additional explanation.

Mark B, thanks for the reminder of how to use stored values. This is an approach whose existence I've been aware of, but that I'd never actually used. So now I have put it into effect — the file where I'm working now is a relatively small one, but I'll use it on some of my huge files and look for a performance boost. Thanks all around.

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 1:18pm

Ok, this is to extend the learning-in-public exercise, involving the two Marks, Scott H, and others. Situation:
  • I have a relatively large file, with ~1000 items;
  • Each item in the file has several numeric values, with relations to each other. Let's say I am entering numbers in US dollars, and want to see their Chinese RMB equivalent. Or I am entering distances in miles and want to see kilometers.
  • Right now I have a Rule, in the prototype, which requires every item to perform a set of calculations. For instance, $RMBSum=$DollarSum*6.4;$KMDistance=$MileDistance/.6; and so on.
  • I recognize that this is computation-heavy, in that it is requiring each item to run the calculations. So I am looking for the right way to assign the calculations to a stored note.

I also recognize that this is different from $DisplayExpression, because that is an expression, telling each note how to render its displayed name. If I have a stored note with the rule $RMBSum=$DollarSum/6.4, and then tell the prototype $RMBSum=$RMBSum(/refnote), that obviously doesn't work, because the value will be whatever specific number is in the reference note.

Conceptually I know that I am looking for something like $DisplayExpression, for these new values I am creating (like, $RMBExpression or $KMDistanceExpression). Is there an easy way to do this, or is this the kind of "simplification" that in fact creates more work and problems than it solves?

Edited to fix typos in RMB and KM calculations.

Title: Re: Odd question on truncated $DisplayExpression
Post by Mark Bernstein on Apr 18th, 2016, 2:19pm

First, my guess is that your document will be Fast Enough.

Are the values likely to change?  If not, you could try

   $RMBSum |= $DollarSum*6.4 ;

If there's already an RMB value, |= does nothing.  If not, it will compute the RMB value and store it.  This might be slightly faster.

You might also consider whether this can be done with an edict rather than a rule.

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 2:31pm

Good tips, thanks. Yes, I see how |= would be my friend in skipping past the great majority of the calculations.

Title: Re: Odd question on truncated $DisplayExpression
Post by Mark Anderson on Apr 18th, 2016, 2:53pm

As the RMB/KM value depends on the local Dollar/Mile value I'm not sure there's much optimisation to do. The conversion factor in each case is inherited from the prototype via the rule so doesn't have to be stored locally. I can think of 2 optimisations...

Note for beginners: the following is not the sort of thing you need to worry about just yet. Optimisation only begins to matter as your document grows in size and you think you detect a slow-down in usual performance, e.g. rules take a while to update

Apologies, for the latter above, but as this is may be read by all sorts of users, I don't want to confuse someone by them trying to optimise their first file that only has a few notes!

1. Consider moving Rules -> Edicts.
Edicts are rules, run occasionally (see the next sub-tab to the 'rule' in the Action Inspector). Thus the same code, run in either a rule or an edict, has the same outcome (there's no point using both at the same time for the same task!). The difference is how often the code runs. An edict runs on creation (and change?) of the code therein, and thence about once per hour. By comparison, rules cycle continuously starting the next cycle as soon as the current one has finished. Edicts (all of them in the current doc) can be run on demand, for one cycle only, by calling menu File -> Update Agents Now.

In your example, the RMB/KM figure only needs updating if the Dollar/Mile figure changes (or the exchange factor is changed in the prototype). You could move this code to a stamp, but here you've too many notes to track and manual [sic] stamping is prone to human error. So here an edict seems a reasonable trade off.  Either edit the Dollar/Mile attribute and let the doc catch up in slow time or, if in a hurry to use the converted values, run File -> Update Agents Now to run all the edicts once.

The Agents & Rules sub-tab of the Tinderbox Inspector shows you when the edicts

By using an edict, you should be able to see that the action code is being run less often in aggregate. The possible downside? That you edit a Dollar/Mile figure and use the RMB/KM one without either waiting for the edict to run or manually calling an update. On balance in this scenario, that's unlikely.

2. Exercise control from the Rule or Edict.
Both can be disabled via $RuleDisabled and $EdictDisabled. The Inspector for each has a tick-box for that too. BUT… these attributes are intrinsic which means if you turn them off in the prototype that doesn't cascade to the inheriting notes. So, disabling a rule/edict in the prototype simply stops it running in the prototype. Generally, that is exactly the desired effect. However, if it doesn't affect inherited behaviour if the code runs in the prototype then you can employ this neat trick. This is the version for a rule (swap out $RuleDisabled for $EdictDisabled to use with an edict).

if($Prototype & $RuleDisabled($Prototype)==false){

This checks we have a $Prototype (i.e. we aren't a prototype) and that the prototype's rule is note disabled. Thus when the prototype rule is disabled, so it is in all inheriting notes. This if() structure routes around the non-inheritance of disablement attributes.

Before someone points it out, yes, the rule/edit still runs, but only to do the if test. If the result is false, all code inside the {} is ingnored. As the latter it what is loading the doc, performance can be adjusted.

3. Store variables.
In your example, the two conversion factors are only used in the rule. The fact you only see them in the rule is minor. If you need to change them, you do so in situ in the rule and the change inherits as part of the rule. But let's suppose you've 3 or 4 rules using the same conversions. Now you have 4 places to make each change.  So, add two notes, 'Currency Factor' and 'Distance Factor' (OK, the miles:km factor isn't likely to change, but lets just assume it might). In each, make $MyNumber the KA and put the conversion facto in KA. Now the rule in our example is  is:

$RMBSum=$DollarSum*$MyNumber("Currency Factor");$KMDistance=$MileDistance/$MyNumber("Mileage Factor");

You could use different attributes for the factors so both could be stored in the prototype. In that case the notes storing the factor could be used to set the appribute(s) in the prototype:

$CurrencyFactor("pConversions") = $MyNumber;

and in the other note:

$MileageFactor("pConversions") = $MyNumber;

Now prototype 'pConversions' has the rule:


4. Consider |= assignments as per MB's post above.

That's probably enough for this post.  Don't forget that while it's probably a good idea to try these ideas in a samll test doc, you don't need such optimisations for a 20-item to-do list.  :)

Title: Re: Odd question on truncated $DisplayExpression
Post by J Fallows on Apr 18th, 2016, 3:02pm

Thank you, both Marks!

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.