Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Commifying sensibly

by oko1 (Deacon)
on Dec 01, 2008 at 14:57 UTC ( #727108=snippet: print w/ replies, xml ) Need Help??

Description:

Recently, I was thinking about that example in the docs where they demonstrate a method for inserting commas into a numerical string. Now, I realize that they're trying to illustrate a specific mechanism with regexes... but that thing is just clumsy and awful and obfuscated for any Perl beginner. So, just for my own entertainment, I decided to see how I'd do it "for real" - i.e., in the best way possible rather than by this contrived method.

Herewith, humbly, I present a couple of options. :)

#!/usr/bin/perl -w
use strict;

die "Usage: ", $0 =~ /([^\/]+)$/, " <numeric_string>\n"
    unless @ARGV && $ARGV[0] =~ /^\d+$/;
my ($c, @list);
for (reverse split //, $ARGV[0]){
    unshift @list, $c++ % 3 || $c == 1 ? $_ : "$_,";
}
print @list;

# Or, instead of "cheating" with an unquoted list, we could
# aggregate to a string. It's not quite as neat, though. :(
#
# my ($c, $out);
# for (reverse split //, $ARGV[0]){
#     $out = $c++ % 3 || $c == 1 ? "$_$out" : "$_,$out";
# }
# print "$out\n";
Comment on Commifying sensibly
Download Code
Re: Commifying sensibly
by Limbic~Region (Chancellor) on Dec 01, 2008 at 15:47 UTC
    oko1,
    Recently, I was thinking about that example in the docs where they demonstrate a method for inserting commas into a numerical string.

    You mean the one from perlfaq5?

    but that thing is just clumsy and awful and obfuscated for any Perl beginner. So, just for my own entertainment, I decided to see how I'd do it "for real" - i.e., in the best way possible rather than by this contrived method.

    I agree that many of the solutions in the FAQ are written more as a cook book rather than as a tutorial. On the other hand, do you honestly feel that your solutions are any better if your target audience is a perl beginner?

    If that is your target audience, I would have gone with something a bit more verbose.

    • Return undef if input is not numeric - perhaps using Scalar::Util's looks_like_number()
    • Return input in tact if it shouldn't be commified (Inf, NaN, already commified, etc) - perhaps using a different sub
    • Perform commification in step-by-step atomic units of work

    Since it seems your intended goal was to educate beginners, each step should be preceded by the appropriate amount of comments. It may not be obvious what a regex is doing so you could recommend YAPE::Regex::Explain. They may not have considered edge cases, so rather than incorporate them into a single step that is doing something else - break it out on its own statement.

    Cheers - L~R

          You mean the one from perlfaq5?
      

      Well, yes; I don't know of any others.

          do you honestly feel that your solutions are any better if your target audience is a perl beginner?
      

      [blink] Perhaps I'm being a tad sensitive, but I feel like you're taking an aggressive tone here and in the rest of your reply. Did I flick you on the raw somewhere? If so, I apologize; my post here was not meant as an insult to anyone.

      To answer your question: my solution was not intended as a replacement for the code in the FAQ - I'd already said that the example was intended to demonstrate a point (one which my code does not demonstrate.) It is not intended for beginners; my point was that I would never use the regex in the example since it is an obfuscated, baroque, and unnecessarily tortuous approach to solving a simple problem, and that there are more readable, reasonable ways to do it. My only reason for mentioning beginners at all was to note that the code in the FAQ is not suitable for them; I did not say or imply that mine is. As for the rest of your reply... please feel free to explain to me why all of these things are not done in that FAQ, and why I should do them. If your demands are reasonable, then the FAQ should have followed them, no?

      I assure you, by the way, that if I was writing for beginners, I would do so quite well - perhaps better than anyone who chooses to criticize me on that topic. I'm a teacher, and have been for most of career; that is, I specialize in explaining things to beginners. Which is explicitly not what I was doing here.

      The bit of code that I posted here simply explored an approach, with a possible variation, that I thought was reasonable for the problem. Again, if was not intended to be an insult or an attack on anyone, and I'm sorry that you appear to be taking it that way.


      --
      "Language shapes the way we think, and determines what we can think about."
      -- B. L. Whorf
        oko1,
        ... I feel like you're taking an aggressive tone here and in the rest of your reply.

        Hrm. Not my intention at all. I often miss social cues and find that my direct questions are met with an unintended response. This can be even more exacerbated online where the only subtle indications we have to go on are smileys. I will defer explaining the reason for my question until later as it will become clear.

        It is not intended for beginners;...My only reason for mentioning beginners at all was to note that the code in the FAQ is not suitable for them; I did not say or imply that mine is

        I wasn't sure if you were trying to imply this was for beginners or not. That is why I said "if your target audience..." a number of times. I suppose a much more tactful approach would have been a /msg "Was this intended for beginners?". If the answer had been yes, as I had incorrectly assumed, then I would have stood by my reply as an objective constructive critism on how to more adeptly approach your audience. Now that I have the benefit of your background, I can see how my response would be offensive and I retract it. I had Super Searched your nodes before replying to see if you had posted tutorials or "how to"s in the past. I drew my conclusion from incomplete data and I concluded wrong - my apologies.

        While I incorrectly concluded that your post was intended for beginners, you seem to have incorrectly concluded that my reply was intended as being aggressive. Now, I must apologize again for something I can only guess has happened as a result of my reply. While I have not voted on your node (I was waiting to hear your response), I can bet you probably received a number of downvotes due to my reply. If that has happened, I apologize profusely and will now upvote both your root node and your reply as I can see it was I that was way off base.

        Cheers - L~R

Re: Commifying sensibly
by oshalla (Deacon) on Dec 02, 2008 at 17:34 UTC

    Appears not to work if there's a decimal '.' ? Or a sign ?

    Just for the hell of it:

    use strict ; use warnings ; foreach my $t (1234567, 123.4567, -123456, .123456, '.1234567', -10* +*1000) { printf "%12s -> oko1:%12s, faq:%12s\n", $t, commify($t), commify_f +aq($t) ; } ; sub commify { my ($s) = @_ ; my @list = () ; my $c = 0 ; for (reverse split //, $s){ unshift @list, $c++ % 3 || $c == 1 ? $_ : "$_,"; } ; return join '', @list ; } ; sub commify_faq { local $_ = shift ; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/ ; return $_ ; } ;
    gives:
         1234567 -> oko1:   1,234,567, faq:   1,234,567
        123.4567 -> oko1:  12,3.4,567, faq:    123.4567
         -123456 -> oko1:   -,123,456, faq:    -123,456
        0.123456 -> oko1:  0.,123,456, faq:    0.123456
        .1234567 -> oko1:  .1,234,567, faq:    .1234567
            -inf -> oko1:       -,inf, faq:        -inf
    
    which, from a pedagogical stand point, may be useful in itself :-)

      Oh, well spotted!++ I was only thinking of integers. Since the whole concept is flawed, and there doesn't seem to be an obvious way to fix it, it's back to the drawing board! :)


      --
      "Language shapes the way we think, and determines what we can think about."
      -- B. L. Whorf

Back to Snippets Section

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2014-09-16 06:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (157 votes), past polls