Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Match Numeric Range

by roboticus (Chancellor)
on Aug 18, 2015 at 12:43 UTC ( [id://1139008]=note: print w/replies, xml ) Need Help??


in reply to Match Numeric Range

PilotinControl:

If you're just wanting to simplify conditional statements like the ones you've shown, I typically use a function like this:

use strict; use warnings; sub between { my ($min, $val, $max) = @_; return $val>=$min && $val<=$max; } for my $range (450, 475, 500, 550, 450, 350, 250, 100) { print "Range: $range\n"; if (between(300, $range, 400)) { exit; } if (between(425, $range, 500)) { print "LIGHTS ON\n"; } }
$ perl t.pl Range: 450 LIGHTS ON Range: 475 LIGHTS ON Range: 500 LIGHTS ON Range: 550 Range: 450 LIGHTS ON Range: 350

If you need to get fancier and build your functions dynamically (such as reading the values from a file), I tend to use a closure to generate them:

#!/usr/bin/env perl use strict; use warnings; # Build the functions my @tests; while (<DATA>) { my ($min, $max, $message) = split /\s+/, $_, 3; push @tests, make_test_function($min, $max, $message); } my $range = 0; while ($range < 600) { print "Range: $range\n"; for my $test (@tests) { $test->($range); } $range += int(100*rand); } sub make_test_function { my ($min, $max, $message) = @_; return sub { my $val = shift; print $message if $val >= $min and $val <= $max; } } __DATA__ 100 350 In range A 200 500 In range B 300 400 In range C
$ perl t.pl Range: 0 Range: 10 Range: 10 Range: 25 Range: 56 Range: 144 In range A Range: 208 In range A In range B Range: 254 In range A In range B Range: 323 In range A In range B In range C Range: 379 In range B In range C Range: 468 In range B Range: 530 Range: 550 Range: 557

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: Match Numeric Range
by PilotinControl (Pilgrim) on Aug 18, 2015 at 13:53 UTC

    Thanks roboticus...the script is looking for the range of numbers dynamically in real time: 400-500 = Lights Off and 200-300 = Lights On. These numbers are generated via the photo resistor and is read from the serial port. The script is turned on and runs in the backround and once one of those numbers in the specified range has been detected the lights will either turn on or turn off. The while loop freezes my script as its looking for the range of numbers. The loops needs to continually be checking for that range of numbers as it will eventually trigger other things to happen.

      This kind of thing can be okay for progressive checking. I normal dislike this style of code/logic but it seems a good fit for this kind of problem.

      if ( $range > 500 ) { WAT_OP(); } elsif ( $range >= 425 ) { some_op(); } elsif ( $range > 400 ) { some_other_op(); } elsif ( $range > 300 ) { exit 0; } else { complete_tree_op(); }

      You can also do something more dispatchy–

      my @action_tree = ( { test => sub { $_[0] >= 300 && $_[0] <= 400 }, action => sub { print "GUDNITES\n"; CORE::exit(0 +) } }, { test => sub { $_[0] >= 425 && $_[0] <= 500 }, action => sub { print "OHAI\n" } } ); while ( my $signal = <SIGNAL_SOURCE> ) { $_->{test}->($signal) && $_->{action}->() for @action_tree; }

      I'm not advocating either, or that second style of terseness, or any style or approach for that matter. Just expanding the library of options. :P

        Thanks YourMother! This approach worked as expected and with narrowing down the numbers being sent out by the serial monitor I can fine tune the range of the photo resistor to accomplish what I need it too. Thanks to all who answered.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1139008]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-25 04:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found