BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to adapt a piece of JavaScript code for my purposes and it contains the following function:

Since the orignal JS version aparently raised hackles, here's my first attempt at a Perl version along with some code to exercise it:

#! perl -slw use strict; sub func { my $vv = shift; my $bb = 140*24*60*60*1000; ##140 days if( $vv >= $bb ) { ##140 days < 5 months $bb = 8766*60*60*1000;##1 year if( $vv < $bb ) { return( $bb/12 ); } ## 1 year + ##1 month if( $vv < $bb *2 ) { return( $bb/6 ); } ## 2 years + ##2 month if( $vv < $bb *5/2 ) { return( $bb/4 ); } ## 2.5 years + ##3 month if( $vv < $bb *5 ) { return( $bb/2 ); } ## 5 years + ##6 month if( $vv < $bb *10 ) { return( $bb ); } ## 10 years + ##1 year if( $vv < $bb *20 ) { return( $bb*2 ); } ## 20 years + ##2 years if( $vv < $bb *50 ) { return( $bb*5 ); } ## 50 years + ##5 years if( $vv < $bb *100 ) { return( $bb*10 ); } ## 100 years + ##10 years if( $vv < $bb *200 ) { return( $bb*20 ); } ## 200 years + ##20 years if( $vv < $bb *500 ) { return( $bb*50 ); } ## 500 years + ##50 years return( $bb*100 ); ##100 years } $bb /= 2; ##70 days if( $vv >= $bb ) { return( $bb/5 ); } ##14 days $bb /= 2; ##35 days if( $vv >= $bb ) { return( $bb/5 ); } ##7 days $bb /= 7; $bb *= 4; ##20 days if( $vv >= $bb ) { return( $bb/5 ); } ##4 days $bb /= 2; ##10 days if( $vv >= $bb ) { return( $bb/5 ); } ##2 days $bb /= 2; ##5 days if( $vv >= $bb ) { return( $bb/5 ); } ##1 day $bb /= 2; ##2.5 days if( $vv >= $bb ) { return( $bb/5 ); } ##12 hours $bb *= 3; $bb /= 5; ##1.5 day if( $vv >= $bb ) { return( $bb/6 ); } ##6 hours $bb /= 2; ##18 hours if( $vv >= $bb ) { return( $bb/6 ); } ##3 hours $bb *= 2; $bb /= 3; ##12 hours if( $vv >= $bb ) { return( $bb/6 ); } ##2 hours $bb /= 2; ##6 hours if( $vv >= $bb ) { return( $bb/6 ); } ##1 hour $bb /= 2; ##3 hours if( $vv >= $bb ) { return( $bb/6 ); } ##30 mins $bb /= 2; ##1.5 hours if( $vv >= $bb ) { return( $bb/6 ); } ##15 mins $bb *= 2; $bb /= 3; ##1 hour if( $vv >= $bb ) { return( $bb/6 ); } ##10 mins $bb /= 3; ##20 mins if( $vv >= $bb ) { return( $bb/4 ); } ##5 mins $bb /= 2; ##10 mins if( $vv >= $bb ) { return( $bb/5 ); } ##2 mins $bb /= 2; ##5 mins if( $vv >= $bb ) { return( $bb/5 ); } ##1 min $bb *= 3; $bb /= 2; ##3 mins if( $vv >= $bb ) { return( $bb/6 ); } ##30 secs $bb /= 2; ##1.5 mins if( $vv >= $bb ) { return( $bb/6 ); } ##15 secs $bb *= 2; $bb /= 3; ##1 min if( $vv >= $bb ) { return( $bb/6 ); } ##10 secs $bb /= 3; ##20 secs if( $vv >= $bb ) { return( $bb/4 ); } ##5 secs $bb /= 2; ##10 secs if( $vv >= $bb ) { return( $bb/5 ); } ##2 secs return( $bb/10 ); ##1 sec } printf "%f -> %f\n", $_, func( $_ ) for map 10**$_, -2 .. +14; __END__ [18:49:55.78] E:\Chart>junk 0.010000 -> 2500.000000 0.100000 -> 2500.000000 1.000000 -> 2500.000000 10.000000 -> 2500.000000 100.000000 -> 2500.000000 1000.000000 -> 2500.000000 10000.000000 -> 2500.000000 100000.000000 -> 12500.000000 1000000.000000 -> 120000.000000 10000000.000000 -> 900000.000000 100000000.000000 -> 10800000.000000 1000000000.000000 -> 172800000.000000 10000000000.000000 -> 1209600000.000000 100000000000.000000 -> 15778800000.000000 1000000000000.000000 -> 157788000000.000000 10000000000000.000000 -> 1577880000000.000000 100000000000000.000000 -> 3155760000000.000000

It is obviously ripe for refactoring, but can anyone

  1. work out what (beyond:"mapping one number to another") it is doing?
  2. perceive the mapping sufficiently to simplify (preferably:calculate) the mapping?

I'm not sure that you can take much guidance from the comments; as in context, the function does not seem to be being used for anything date or time related?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
li

Replies are listed 'Best First'.
Re: [OT] Mysterious function. (Updated)
by RichardK (Parson) on Apr 23, 2015 at 18:13 UTC

    My _guess_ is that it's working out where to put the graduations when drawing a graph.

    i.e. when the graphed interval is 1 year put tick marks every 1 month, 2 years - ticks every 2 months, .. 500 years - ticks every 50 years. There is some obvious repetition -- you could scale some of the results, as the answer for (100 - 1000) is ten times as big as that for (10 - 100). HTH

      Thank you! Now you've pointed it out, it makes a lot of sense in isolation.

      In the actual example it appears to be called for all three axis, only one of which is date related.

      But then there is some conditional code that is rather opaque; so it might be that it is only used by the months axis.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: [OT] Mysterious function.
by jeffa (Bishop) on Apr 23, 2015 at 17:51 UTC

    I used node.js to produce some interesting edge cases. The values on the left were plugged into this confusing function and the values on the right are the results of the function.

    0 = 2500 24999 = 2500 25000 = 5000 49999 = 5000 50000 = 12500 149999 = 12500 150000 = 25000 224999 = 25000 225000 = 37500 299999 = 37500 300000 = 60000 599999 = 60000 600000 = 120000 1199999 = 120000 1200000 = 300000 3599999 = 300000 3600000 = 600000 5399999 = 600000 5400000 = 900000 10799999 = 900000 10800000 = 1800000 21599999 = 1800000 21600000 = 3600000

    Perhaps you can make some heads or tails out of the pattern, but i cannot. I sincerely hope this helps, however.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Thanks. You inspired a way to work out the transition points:

      I used node.js to produce some interesting edge cases.

      'scuse my ignorance, but does node.js allow you to run JS at the command line?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Excellent! :) Yes, node.js allows you to run JS at the command line. It is quite a handy tool to have at your disposal:

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)