Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: RFC: Seconds2English

by halley (Prior)
on Jul 18, 2003 at 19:53 UTC ( [id://275729]=note: print w/replies, xml ) Need Help??


in reply to RFC: Seconds2English

I did a *much* smaller version of this for an IRC trivia bot some time ago. When I get home this evening, I'll post it in the box below. "Humanizing" data is very important in user interfaces, and I'm tired of so many programs training users to be digital when a good program can train the computer to present things in analog.
# will update this box tonight
I assembled the elements like "4 minutes" in an array, and found truncating them to be useful for most human-scale messages. Most users don't care about the lesser-significant items. Thus, "4 years, 6 months, 3 weeks, 3 days, 17 hours, 52 minutes, and 40 seconds" would get chopped to two or three units, giving "4 years, and 6 months".

I was also working on a 'fuzzy' version which would give nice approximation according to the remainder: "nearly 4 years and 7 months".

--
[ e d @ h a l l e y . c c ]

Replies are listed 'Best First'.
Re: Re: RFC: Seconds2English
by Limbic~Region (Chancellor) on Jul 18, 2003 at 19:59 UTC
    halley,
    The english_min() method would do the truncation you mentioned, but there is no 'fuzzy' version. There was a point where I just needed to stop giving it bloat since my intention wasn't to upload it to CPAN.

    I will be interested to see how your code looks. I dreamed my code up before peaking at the other similar modules as to not be influenced.

    Cheers - L~R

      This is from Text::XSprintf that I've had to put on the back burner. The $mode and stuff is for that module, and the sub below _duration is meant to be called by autogenerated code....

      my %Times=( 1 => 'sec|second', 60 => 'min|minute', 60*60 => 'hour', 60*60*24 => 'day', 60*60*24*365 => 'year' ); sub _dstr{ my ($mult,$mode,$unit)=@_; my $str=$mult; if ($mode!~/^[h#]/) { my @names=split /\|/,$Times{$unit}; $str.=($mode eq 'l' ? " $names[-1]" : " $names[0]"); $str.="s" if $mult!=1; } elsif ($mode eq 'h') { $str.=substr($Times{$unit},0,1); } return $str } sub _duration { my $mode=lc(shift); # my $dur=shift; $mode=~/^[hml#]$/ or $mode="m"; my $negative=$dur<0 ? ($mode eq "l" ? "negative " : $mode eq "m" ? + "neg " : "-") : ""; my @units; foreach my $unit (sort {$b <=> $a} keys %Times) { next unless $unit>1; if ($dur>=$unit) { my $mult=int($dur/$unit); $dur-=$mult*$unit; push @units,_dstr $mult,$mode,$unit; } elsif ($mode eq "#" and @units) { push @units,0; } } if ($dur or $mode eq "#" or not @units) { push @units,_dstr $dur,$mode,1; } $units[-2].=" and ".pop @units if @units>1 and $mode eq 'l'; return $mode ne "#" ? $negative.join( ", ",@units) : $negative.sprintf(join(":",("%02d") x @units +),@units); }

      Anyway, I figured this was similar to some of your stuff and you did mention being curious as to how others have done stuff....


      ---
      demerphq

      <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2024-04-19 08:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found