Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi
Tinderbox Users >> Questions and Answers >> Modulus operator?
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi?num=1187905260

Message started by rtalexander on Aug 23rd, 2007, 5:41pm

Title: Modulus operator?
Post by rtalexander on Aug 23rd, 2007, 5:41pm

Does TB have a mechanism for computing the remainder of one number divided by another (i.e. modulo operator)?

Title: Re: Modulus operator?
Post by rtalexander on 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?

Title: Re: Modulus operator?
Post by Mark Anderson on 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!

Title: Re: Modulus operator?
Post by rtalexander on Aug 23rd, 2007, 6:44pm

I thought of that, but geez, it would be a performance pig.

Title: Re: Modulus operator?
Post by Mark Bernstein on 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

Title: Re: Modulus operator?
Post by Mark Anderson on 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.

Title: Re: Modulus operator?
Post by rtalexander on 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?

Title: Re: Modulus operator?
Post by rtalexander on 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"?




Title: Re: Modulus operator?
Post by Mark Bernstein on 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)


Title: Re: Modulus operator?
Post by Mark Anderson on 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.

Title: Re: Modulus operator?
Post by Mark Bernstein on 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


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.