in reply to Re^2: Seeking a module to convert numbers to words
in thread Seeking a module to convert numbers to words

... or alternatively filter all numbers first in your document, add some if and else rules here and there and create a %hash with this, it depends on what do you need exactly and could be more eficient if you only need to store what you have
  • Comment on Re^3: Seeking a module to convert numbers to words

Replies are listed 'Best First'.
Re^4: Seeking a module to convert numbers to words
by kcott (Archbishop) on Aug 21, 2011 at 15:35 UTC

    Update: My apologies pvaldes. This was not poorly received! I believe I have confused reception to a different post of yours. Probably need new glasses or something. Again, sorry. My original response follows:

    pvaldes, thanks for taking the time to reply. As I'm sure you're aware by now, your response has not been well received. Let's see if we can garner something positive from the exercise.

    In my original prototype code, I had something which is perhaps on par with what you're suggesting. Rather than digging out old versions, this gives an idea of what it may have looked like:

    # TODO - prototype code only! my @num2word = qw{zero one two ... twenty}; ... say q{I have }, $num2word[$apple_count], q{ apples.};

    Moving out of the prototype phase, this code obviously needed to be more robust. I searched around for an existing module without success and, having decided this would be an interesting exercise, came up with the following proof-of-concept:

    After ironing out bugs (mostly to do with output format), I put the non-test parts of this code into a module: Util::Number. Having added to @fixed_test_data as I tested, I have values for regression testing (which is still to do as well as POD).

    I was surprised that I hadn't been able to find any code like this. I decided to ask here and, if no one had any better ideas, look at putting this functionality on CPAN. You know the rest from this thread.

    Here's a quick comparison of the modules mentioned:

    $ perl -Mstrict -wE 'use Number::Spell; say spell_number(100010001001) +' one hundred billion ten million one thousand one $ perl -Mstrict -wE 'use Lingua::EN::Numbers qw{num2en}; say num2en(10 +0010001001)' one hundred billion, ten million, one thousand and, one $ perl -Mstrict -wE 'use Util::Number; say conv_num_to_text(1000100010 +01)' one hundred billion, ten million, one thousand and one

    In closing, providing something substantial will generally be well received whereas "... add some if and else rules here and there ..." will not. As you can see, while I have thrown a few ifs and elses around, there was nothing in your post that suggested how I should do this.

    I recommend you take a look at To Answer, Or Not To Answer.....

    P.S. I haven't downvoted your node: I reckon you've got enough bad press already. :-)

    -- Ken

      In dirty and blooding pseudocode 1- Simplify the idea. You don need all of this

      my @units my @teens my @tens

      You only need this:

      my %number = ( 0 => zero, 1 => one, 2 => two, 3 => three, 4 => four, 5 => five, 6 => +six, 7 => seven, 8 => eight, 9 => nine, 10 => ten, 11 => eleven, 12 = +> twelve, 13 => thirteen, 14 => fourteen, 15 => fifteen, 16 => sixtee +n, 17 => seventeen, 18 => eighteen, 19 => nineteen, 20 => twenty, 30 +=> thirty, 40 => forty, 50 => fifty, 60 => sixty, 70 => seventy, 80 = +> eighty, 90 => ninety);
      No, you don't need a bigger hash, you could make it bigger but this is not necessary probably.

      2 - pick up the whole number, by your preferred method, maybe a regex \d{1,}. Store the number in a variable

      3 -Proceed to parse the number

      if $number is a key in the hash, print its value, end of the history else you need to reduce the problem while $number is not undef extract the last number of the chain with pop if the popped number = 0 forget this number else my $units = this number pop again if you have a zero: good bye zero! else my $teen = this number *10 pop again if you have a zero: good bye zero! else my $hundred = this number my $thereis_a_hundred = true; ... etc, etc ... pop again ... oups, nothing left to pop, we obtain undef and ex +it the loop, my $googolplex = ''; # this variable was not reached, its value +is still the null string, so if you print it nothing occurs } ## print all variables you have collected in reversed position and a +dd some extra strings ## first whe prepare the extra chains, this could be done before also if ($there_is_hundred is true){my $hundred_str = "hundred and "} else {$hundred_str = ''}; if ($there_is_thousand is true){my $thousand_string = " thousand, "} else {$thousand_string = ''}; # ... etc # we finish print ....... %number[$thousand] $thousand_string %number[$hundred] + $hundred_str %number[$teen], %number[$unit]; # and we close all with the required "}"

      This is more or less all that you need, of course you can refine the idea a lot: you can simplify the idea behind there_is_hundred / hundred_str and do all in one steep with one variable, you should also do something with floating numbers, and you should aware that billion could be a very different creature in Europe and in USA and, and, and...

      But in any case, the idea behind all is very simple. Treat the number as a chain, pop the numbers one by one until you have undef, eval the number each time, fill as many variables as digits you have and print all together at the end, including the invisible null variables