Sorry, an error occurred while loading the content.

## Use of 'IfInRange'

Expand Messages
• I d like to use the If In Range command to make a decision how to process numbers. If it s within a certain range, I want to do one thing, and if it s not, I
Message 1 of 10 , Mar 9, 2011
• 0 Attachment
I'd like to use the If In Range command to make a decision how to process
numbers. If it's within a certain range, I want to do one thing, and if it's
not, I want to process it differently. I don't quite understand how I get
the number to be evaluated. Would you use a find first, then use
^\$GetReSubstrings\$ to capture the value of the whole number, followed by its
decimal component as the second value? I want to use the IfInRange on the
second value. Can someone that has used the command show me a working
example? I can adapt to my needs if I see a working sample.

An example of how this might be used is if a decimal number has 0-4 as the
first number after a decimal point. (6.199) If it's within that range, I'd
drop the decimal point and any decimals, thus rounding down to a whole
number. (6) That would leave all the other decimals as needing to be rounded
up to a whole number, such as 199.6, which would become 200.

What is the best way to implement rounding on mixed numbers (different
numbers of decimals, such as 1.34, 2.6666667, etc)? I assume you'd have to
capture the whole number in its own variable, and increment it if the range
of the first decimal is 5-9. (Not in the range 0-4, meaning the 'other'
numbers from the ones already rounded down).

Is there an easier way to do rounding?

Regards,

John

RecipeTools site: http://recipetools.gotdns.com

Beaverton Weather: http://shotsky.gotdns.com

[Non-text portions of this message have been removed]
• I came up with a solution that was a little easier than I thought it would be. Thought I d share it in case anyone else needs it. The key thing here is that
Message 2 of 10 , Mar 9, 2011
• 0 Attachment
I came up with a solution that was a little easier than I thought it would
be. Thought I'd share it in case anyone else needs it. The key thing here is
that the decimals are not fixed length, so simple rounding may not work. The
goal is to round to the nearest whole number, regardless of number of
decimals.

My dataset:
Some text 17.9
Some text 1.23456789
15.567
20.900000

My clip:
;Round numbers based on first character after decimal point
^!Jump Doc_Start
:Round
^!Find "(\d+)\.(\d)(\d+)*" IRS
^!IfError EndRound
^!SetArray %Value%=^\$GetReSubstrings\$
^!If "^%Value2%" => "5" Next ELSE Skip_1
^!Inc %Value1%
^!Replace "(\d+)\.(\d+)" >> "^%Value1%" RS
^!GoTo Round
:EndRound

Regards,
John
RecipeTools site: <http://recipetools.gotdns.com>
http://recipetools.gotdns.com
Beaverton Weather: <http://shotsky.gotdns.com> http://shotsky.gotdns.com

From: ntb-clips@yahoogroups.com [mailto:ntb-clips@yahoogroups.com] On Behalf
Of John Shotsky
Sent: Wednesday, March 09, 2011 11:19
To: ntb-clips@yahoogroups.com
Subject: [Clip] Use of 'IfInRange'

I'd like to use the If In Range command to make a decision how to process
numbers. If it's within a certain range, I want to do one thing, and if it's
not, I want to process it differently. I don't quite understand how I get
the number to be evaluated. Would you use a find first, then use
^\$GetReSubstrings\$ to capture the value of the whole number, followed by its
decimal component as the second value? I want to use the IfInRange on the
second value. Can someone that has used the command show me a working
example? I can adapt to my needs if I see a working sample.

An example of how this might be used is if a decimal number has 0-4 as the
first number after a decimal point. (6.199) If it's within that range, I'd
drop the decimal point and any decimals, thus rounding down to a whole
number. (6) That would leave all the other decimals as needing to be rounded
up to a whole number, such as 199.6, which would become 200.

What is the best way to implement rounding on mixed numbers (different
numbers of decimals, such as 1.34, 2.6666667, etc)? I assume you'd have to
capture the whole number in its own variable, and increment it if the range
of the first decimal is 5-9. (Not in the range 0-4, meaning the 'other'
numbers from the ones already rounded down).

Is there an easier way to do rounding?

Regards,

John

RecipeTools site: http://recipetools.gotdns.com

Beaverton Weather: http://shotsky.gotdns.com

[Non-text portions of this message have been removed]

[Non-text portions of this message have been removed]
• ... Simple rounding should work: ^!Jump 1 ^!Find d+ . d+ RS ^!IfError End ^!InsertText ^\$Calc(ROUND(^\$GetSelection\$))\$ ^!Goto Skip_-3
Message 3 of 10 , Mar 9, 2011
• 0 Attachment
John Shotsky <jshotsky@...> wrote:
>
> The key thing here is
> that the decimals are not fixed length, so simple rounding may not work. The
> goal is to round to the nearest whole number, regardless of number of
> decimals.
>
> My dataset:
> Some text 17.9
> Some text 1.23456789
> 15.567
> 20.900000
>
> My clip:
> ;Round numbers based on first character after decimal point
> ^!Jump Doc_Start
> :Round
> ^!Find "(\d+)\.(\d)(\d+)*" IRS
> ^!IfError EndRound
> ^!SetArray %Value%=^\$GetReSubstrings\$
> ^!If "^%Value2%" => "5" Next ELSE Skip_1
> ^!Inc %Value1%
> ^!Replace "(\d+)\.(\d+)" >> "^%Value1%" RS
> ^!GoTo Round
> :EndRound
>

Simple rounding should work:

^!Jump 1
^!Find "\d+\.\d+" RS
^!IfError End
^!InsertText ^\$Calc(ROUND(^\$GetSelection\$))\$
^!Goto Skip_-3
• Yes, it does work. Thanks! Regards, John RecipeTools site: http://recipetools.gotdns.com Beaverton Weather:
Message 4 of 10 , Mar 9, 2011
• 0 Attachment
Yes, it does work. Thanks!

Regards,
John
RecipeTools site: <http://recipetools.gotdns.com>
http://recipetools.gotdns.com
Beaverton Weather: <http://shotsky.gotdns.com> http://shotsky.gotdns.com

From: ntb-clips@yahoogroups.com [mailto:ntb-clips@yahoogroups.com] On Behalf
Of diodeom
Sent: Wednesday, March 09, 2011 15:33
To: ntb-clips@yahoogroups.com
Subject: [Clip] Re: Use of 'IfInRange'

John Shotsky <jshotsky@...> wrote:
>
> The key thing here is
> that the decimals are not fixed length, so simple rounding may not work.
The
> goal is to round to the nearest whole number, regardless of number of
> decimals.
>
> My dataset:
> Some text 17.9
> Some text 1.23456789
> 15.567
> 20.900000
>
> My clip:
> ;Round numbers based on first character after decimal point
> ^!Jump Doc_Start
> :Round
> ^!Find "(\d+)\.(\d)(\d+)*" IRS
> ^!IfError EndRound
> ^!SetArray %Value%=^\$GetReSubstrings\$
> ^!If "^%Value2%" => "5" Next ELSE Skip_1
> ^!Inc %Value1%
> ^!Replace "(\d+)\.(\d+)" >> "^%Value1%" RS
> ^!GoTo Round
> :EndRound
>

Simple rounding should work:

^!Jump 1
^!Find "\d+\.\d+" RS
^!IfError End
^!InsertText ^\$Calc(ROUND(^\$GetSelection\$))\$
^!Goto Skip_-3

[Non-text portions of this message have been removed]
• ... John, Given the subject... Take 199.6 pounds of flour, 6.199 pounds of rice, 1.34 pounds of salt and 2.6666667 pounds of sugar. Now you could check the
Message 5 of 10 , Mar 10, 2011
• 0 Attachment
--- In ntb-clips@yahoogroups.com, "John Shotsky" <jshotsky@...> wrote:
>
> I'd like to use the If In Range command to make a decision
> how to process numbers. If it's within a certain range, I want
> to do one thing, and if it's not, I want to process it
> differently. I don't quite understand how I get
> the number to be evaluated (...) Can someone that has used the
> command show me a working example?

John,

Given the subject...

'Take 199.6 pounds of flour, 6.199 pounds of rice, 1.34 pounds of salt and 2.6666667 pounds of sugar.'

Now you could check the first number after the decimal point with the following clip (click OK after each match):

^!Jump Doc_Start
:Start
^!Find "\d{1,}\.(\d)\d{0,}" RS
^!IfError End
^!Set %dig%=^\$GetReSubstrings\$
^!IfInRange ^%dig% 0..4 True Else False
:True
^!Info Yes, it's in that range!
^!Goto Start
:False
^!Info No, it's not in that range!
^!Goto Start

But I don't think this a better approach to rounding than the solution given by diodeom and what we've discussed in topic #21513 just a few weeks ago.

Regards,
Flo
• ... For large files these time-consuming iterations could be cut approximately in half if confined only to numbers that require rounding up: ^!Jump 1 ^!Find
Message 6 of 10 , Mar 10, 2011
• 0 Attachment
>
> ^!Jump 1
> ^!Find "\d+\.\d+" RS
> ^!IfError End
> ^!InsertText ^\$Calc(ROUND(^\$GetSelection\$))\$
> ^!Goto Skip_-3
>

For large files these time-consuming iterations could be cut approximately in half if confined only to numbers that require rounding up:

^!Jump 1
^!Find "\d+(?=\.[5-9])" RS
^!IfError Done
^!InsertText ^\$Calc(^\$GetSelection\$+1)\$
^!Goto Skip_-3
:Done
^!Replace "\d+\K\.\d+" >> "" WARS

Similarly, when rounding to decimals:

^!Set %x%=^?{(H=3)Round to==10s^=1|_100ths^=2|1000ths^=3}
^!Set %y%=1^\$StrFill(0;^%x%)\$
^!Jump 1
^!Find "\d+\.\d{^%x%}[5-9]\d*+" RS
^!IfError Done
^!InsertText ^\$Calc(ROUND(^\$GetSelection\$*^%y%)/^%y%;^%x%)\$
^!Goto Skip_-3
:Done
^!Replace "\d+\.\d{^%x%}\K\d+" >> "" WARS
• Thanks, Flo, I wanted to see an example of proper usage of that command to see how to implement it. It turns out that my example was a poor one, but Dio s
Message 7 of 10 , Mar 10, 2011
• 0 Attachment
Thanks, Flo,

I wanted to see an example of proper usage of that command to see how to
implement it. It turns out that my example was a poor one, but Dio's
solution does work great for the example I provided. I have other needs that
aren't exactly the same, where this command will probably be used, and Round
cannot be used, since the 'break point' I'm looking for isn't at 5.

Consider how you'd handle converting decimals to fractions, when you are
restricted to fractions of 1/16 or larger. Only /16, /8 /4 /3 and /2 are
permitted. When a decimal falls between the natural break between these
fractions, what is the best way to determine which fraction should be used?
This is actually the problem I was trying to resolve in a better way than my
current kludge, which uses classes, but isn't accurate for numbers between
15/16 and the next whole number. If the decimal is closer to 15/16 than the
next whole number, I'd choose the fraction, but when it's closer to the
whole number, I'd want to round up to the whole number. After I played
around with it for a few hours, I decided I need a different approach, and
thought perhaps IfInRange would work better.

Regards,

John

RecipeTools site: <http://recipetools.gotdns.com>
http://recipetools.gotdns.com

Beaverton Weather: <http://shotsky.gotdns.com> http://shotsky.gotdns.com

From: ntb-clips@yahoogroups.com [mailto:ntb-clips@yahoogroups.com] On Behalf
Of flo.gehrke
Sent: Thursday, March 10, 2011 00:38
To: ntb-clips@yahoogroups.com
Subject: [Clip] Re: Use of 'IfInRange'

--- In ntb-clips@yahoogroups.com <mailto:ntb-clips%40yahoogroups.com> ,
"John Shotsky" <jshotsky@...> wrote:
>
> I'd like to use the If In Range command to make a decision
> how to process numbers. If it's within a certain range, I want
> to do one thing, and if it's not, I want to process it
> differently. I don't quite understand how I get
> the number to be evaluated (...) Can someone that has used the
> command show me a working example?

John,

Given the subject...

'Take 199.6 pounds of flour, 6.199 pounds of rice, 1.34 pounds of salt and
2.6666667 pounds of sugar.'

Now you could check the first number after the decimal point with the
following clip (click OK after each match):

^!Jump Doc_Start
:Start
^!Find "\d{1,}\.(\d)\d{0,}" RS
^!IfError End
^!Set %dig%=^\$GetReSubstrings\$
^!IfInRange ^%dig% 0..4 True Else False
:True
^!Info Yes, it's in that range!
^!Goto Start
:False
^!Info No, it's not in that range!
^!Goto Start

But I don't think this a better approach to rounding than the solution given
by diodeom and what we've discussed in topic #21513 just a few weeks ago.

Regards,
Flo

[Non-text portions of this message have been removed]
• Thanks, again, Dio! Time is of consideration here, as some of my files are over 1M and take up to 1/2 hour to complete. I ve been concentrating on ways to cut
Message 8 of 10 , Mar 10, 2011
• 0 Attachment
Thanks, again, Dio!

Time is of consideration here, as some of my files are over 1M and take up
to 1/2 hour to complete. I've been concentrating on ways to cut processing
time, and one of those ways is in not capturing things that don't need to be
captured. It's easy to use parens to group things, but it takes some thought
to insert text in front of, or in the middle of a line without capturing
anything. \K is my friend here, but the look-aheads are less 'friendly' to
me.

I will certainly use what you've provided below, as it is similar to my
previous approach, where only the lines needing rounding up were processed
in the loop.

Regards,

John

RecipeTools site: <http://recipetools.gotdns.com>
http://recipetools.gotdns.com

Beaverton Weather: <http://shotsky.gotdns.com> http://shotsky.gotdns.com

From: ntb-clips@yahoogroups.com [mailto:ntb-clips@yahoogroups.com] On Behalf
Of diodeom
Sent: Thursday, March 10, 2011 05:55
To: ntb-clips@yahoogroups.com
Subject: [Clip] Re: Use of 'IfInRange'

>
> ^!Jump 1
> ^!Find "\d+\.\d+" RS
> ^!IfError End
> ^!InsertText ^\$Calc(ROUND(^\$GetSelection\$))\$
> ^!Goto Skip_-3
>

For large files these time-consuming iterations could be cut approximately
in half if confined only to numbers that require rounding up:

^!Jump 1
^!Find "\d+(?=\.[5-9])" RS
^!IfError Done
^!InsertText ^\$Calc(^\$GetSelection\$+1)\$
^!Goto Skip_-3
:Done
^!Replace "\d+\K\.\d+" >> "" WARS

Similarly, when rounding to decimals:

^!Set %x%=^?{(H=3)Round to==10s^=1|_100ths^=2|1000ths^=3}
^!Set %y%=1^\$StrFill(0;^%x%)\$
^!Jump 1
^!Find "\d+\.\d{^%x%}[5-9]\d*+" RS
^!IfError Done
^!InsertText ^\$Calc(ROUND(^\$GetSelection\$*^%y%)/^%y%;^%x%)\$
^!Goto Skip_-3
:Done
^!Replace "\d+\.\d{^%x%}\K\d+" >> "" WARS

[Non-text portions of this message have been removed]
• ... No need to bother with ROUND at all: ^!Set %x%=^?{(H=3)Round to==10s^=1|_100ths^=2|1000ths^=3} ^!Jump 1 ^!Find d+ . d{^%x%}[5-9] d*+ RS ^!IfError Done
Message 9 of 10 , Mar 10, 2011
• 0 Attachment
>
> Similarly, when rounding to decimals:
>

No need to bother with ROUND at all:

^!Set %x%=^?{(H=3)Round to==10s^=1|_100ths^=2|1000ths^=3}
^!Jump 1
^!Find "\d+\.\d{^%x%}[5-9]\d*+" RS
^!IfError Done
^!InsertText ^\$Calc(^\$GetSelection\$;^%x%)\$
^!Goto Skip_-3
:Done
^!Replace "\d+\.\d{^%x%}\K\d+" >> "" WARS
• John, To find the nearest fraction is just an extension of the normal technique for rounding: adding .5 to the number and truncating. In your case, extract the
Message 10 of 10 , Mar 10, 2011
• 0 Attachment
John,

To find the nearest fraction is just an extension of the normal technique for
rounding: adding .5 to the number and truncating.

In your case, extract the decimal portion (x), multiply by 16, add .5 and then
truncate:

Int(x * 16 + 0.5)

The result will be the nearest 16th to your original number.

This is similar to the fence post problem in that there are 17 possible results
for the 16 intervals: 0 thru 16. I would create a 17 element static array
containing
the strings that you want to display for each value (such as "1/16", "1/8",
"3/16", "1/4", etc), the 17th one being blank. Use the result+1 to index
into the array. You would only need to test for when the result equals 16 in
which case you need to add one to the original integer.

This should be faster than a lot of tests for 16 conditions. [Remember to turn
screen update off <g>]

HTH

Namaste', Art

At 03/10/2011 05:59, John wrote:
<snip>
>Consider how you'd handle converting decimals to fractions, when you are
>restricted to fractions of 1/16 or larger. Only /16, /8 /4 /3 and /2 are
>permitted. When a decimal falls between the natural break between these
>fractions, what is the best way to determine which fraction should be used?
>This is actually the problem I was trying to resolve in a better way than my
>current kludge, which uses classes, but isn't accurate for numbers between
>15/16 and the next whole number. If the decimal is closer to 15/16 than the
>next whole number, I'd choose the fraction, but when it's closer to the
>whole number, I'd want to round up to the whole number. After I played
>around with it for a few hours, I decided I need a different approach, and
>thought perhaps IfInRange would work better.
Your message has been successfully submitted and would be delivered to recipients shortly.