Welcome, Guest. Please Login
Tinderbox
  News:
IMPORTANT MESSAGE! This forum has now been replaced by a new forum at http://forum.eastgate.com and no further posting or member registration is allowed. The forum is still accessible via read-only access for reference purposes. If you wish to discuss content here, please use the new forum. N.B. - posting in the new forum requires a fresh registration in the new forum (sorry - member data can't be ported).
  HomeHelpSearchLogin  
 
Pages: 1
Send Topic Print
Modulus operator? (Read 17121 times)
rtalexander
Full Member
*
Offline



Posts: 37

Modulus operator?
Aug 23rd, 2007, 5:41pm
 
Does TB have a mechanism for computing the remainder of one number divided by another (i.e. modulo operator)?
Back to top
 
 
  IP Logged
rtalexander
Full Member
*
Offline



Posts: 37

Re: Modulus operator?
Reply #1 - Aug 23rd, 2007, 5:53pm
 
After searhing a bit, I've concluded that TB does not, if fact, have a mod operator. That being the case, I decided to cobble one up using repeated subtraction, but I find my effort thwarted as TB does not have a looping construct in its action language. So, is there someway to write a recursive action that I could use to compute a mod b? Am I missing something here?
Back to top
 
 
  IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: Modulus operator?
Reply #2 - Aug 23rd, 2007, 6:39pm
 
How about runCommand() - needs v4.0.0+ - using that to call a shell script?  I'll leave it to a more experienced shell scripter to tell you what that script should be!
Back to top
 
 

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
rtalexander
Full Member
*
Offline



Posts: 37

Re: Modulus operator?
Reply #3 - Aug 23rd, 2007, 6:44pm
 
I thought of that, but geez, it would be a performance pig.
Back to top
 
 
  IP Logged
Mark Bernstein
YaBB Administrator
*
Offline

designer of
Tinderbox

Posts: 2871
Eastgate Systems, Inc.
Re: Modulus operator?
Reply #4 - Aug 23rd, 2007, 10:19pm
 
No modulus operator, currently.  (We had one planned for 4.0, but asked ourselves, "Will anyone care?"  It's not hard to add.)

On runCommand: it might not be a performance issue, if you don't need to update the value often.  For example, a container's  OnAdd action doesn't really care about performance, since it's run only occasionally.  Similarly, one-shot rules (either self-deleting or using |= or using a completion flag) can tolerate the performance hit.

On repeated subtraction: you'd be better off using division, floor, and multiplication.  But you don't have floor, either. In the most common case of modulo 2 (even/odd), round will serve.

What do you want to do with mod?  And do you have a preference for

    mod($theNumber,7)    

over

    $theNumber%7
Back to top
 
 
WWW   IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: Modulus operator?
Reply #5 - Aug 24th, 2007, 4:06am
 
I'd observe from the sidelines that mod($TheNumber,7) strikes me as the more obvious syntax for the general learner, albeit more verbose that the other suggestion.
Back to top
 
 

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
rtalexander
Full Member
*
Offline



Posts: 37

Re: Modulus operator?
Reply #6 - Aug 24th, 2007, 5:23pm
 
I agree with Mark Anderson' I think that mod($theNumber,7) is easier to read.

Any chance of getting a hook into Tinderbox from Ruby (preferred) or Python?
Back to top
 
 
  IP Logged
rtalexander
Full Member
*
Offline



Posts: 37

Re: Modulus operator?
Reply #7 - Aug 24th, 2007, 6:07pm
 
Consider the following action, where initially  (for example) Accumulator1=15. Given this initial value, the action, when run, should result in Accumulator2 having a value of 1, indicating that Accumulator1 is odd. However, the value that I get for Accumulator2 is 0, which should only be the case if Accumulator1 has a value that is even, which it does not in this case.

if((2*round($Accumulator1/2))>$Accumulator1) {Accumulator2=1} else {Accumulator2=0};

To get this desired behavior, I find that I must factor out the arithmetic expression from the "if" and assign the result to a temporary attribute, an then use the temporary in the conditional expression, as in:

Accumulator2=2*round($Accumulator1/2);if($Accumulator2>$Accumulator1) {Accumulator2=1;} else {Accumulator2=0;};

The latter code works as desired, but the former does not. So, it appears that (at least) this arithmetic expression cannot be part of the conditional expression. This being the case, what can of expression can be evaluated in the conditional expression of an "if"?



Back to top
 
 
  IP Logged
Mark Bernstein
YaBB Administrator
*
Offline

designer of
Tinderbox

Posts: 2871
Eastgate Systems, Inc.
Re: Modulus operator?
Reply #8 - Aug 24th, 2007, 11:22pm
 
On the hooks to Python, Ruby, or what you will, please see the manual (and discussion of runCommand earlier in this thread!)

On the evaluation issue, it is possible that you need to add parentheses in the query to clarify order of evaluation; I'm not certain (it's late, I have to drive all day in a few hours, and I've had a very long day today) whether a*b>c with no parens parses as

     (a*b)>c

or

    a*(b>c)

Back to top
 
 
WWW   IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: Modulus operator?
Reply #9 - Aug 25th, 2007, 6:04pm
 
@rtalexander. I think I have an answer for you and a workaround that allows your syntax #1. Before doing the latter it's useful to see how why it's needed. FWIW, all the testing for this post was done in TB v4.0.0 unsaved new TBX (noted in case the TBX being saved or not has some bearing).

You're using the post v3.0.0 conditional form:

    if(query){condition1}else{condition2}

So the problem is one of what a query will allow in terms of expressions. After some hours of tinkering I believe TB queries don't support expressions outside export codes that support expressions.  IOW, whilst the main app now deprecates export codes internally, queries are  - for now - out of step. For instance, neither of these work as you might expect

    ($MyNum4+2)>$Accumulator1
   ($MyNum4+$MyNum3)>$Accumulator1


All is not lost!. There is a workaround, albeit using now-deprecated export codes in an action, in this case ^value():

    if(^value((2*round($Accumulator1/2)))>$Accumulator1) {Accumulator2=1} else {Accumulator2=0}

As it may not be immediately obvious to the casual reader, the above technique uses the fact that decimal places from x.50 and above round upwards. Thus twice round(half of 15) is 16.
Back to top
 
« Last Edit: Aug 27th, 2007, 6:19pm by Mark Anderson »  

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
Mark Bernstein
YaBB Administrator
*
Offline

designer of
Tinderbox

Posts: 2871
Eastgate Systems, Inc.
Re: Modulus operator?
Reply #10 - Aug 27th, 2007, 4:49pm
 
Mark Anderson is correct: Tinderbox 4.0.0 comparison queries must have the form

      if( attributeName1 > value) {....

or

     if( attributeName1 > $attributeRef(target)) {....

In other words, you can't do arithmetic or call functions inside a query.  


      if( round($v1&5/3) >3) { ...    <---- NO!

Without loss of generality, you can always store the intermediate values:

     v1=round($Attrib1*5/3);if(v1>3) { ...    <---- OK

Back to top
 
 
WWW   IP Logged
Pages: 1
Send Topic Print