Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Need help comparing 4 dates (sort errors?)

by BrowserUk (Patriarch)
on Oct 03, 2010 at 05:24 UTC ( [id://863144]=note: print w/replies, xml ) Need Help??


in reply to Need help comparing 4 dates

Comparing more than two values--is sorting.

In theory, this should work(Update:see 2 posts down for fixed code):

#! perl -slw use warnings; use strict; use Data::Dumper; use Date::Manip; print scalar <DATA>; while (<DATA>) { chomp; my @dates = split '~'; my $label = shift @dates; my @order = map $_+1, sort{ Date_Cmp( $dates[ $a ], $dates[ $b ] ); } 0 .. $#dates; print join "\t", $label, @order; } __DATA__ EVENT JIM BOB SAM JACK PTRED~09/29/10 03:23:05 PM ~09/28/10 02:21:09 PM ~09/26/10 11:00:03 AM + ~09/27/10 09:33:41 PM RED~08/29/10 01:55:00 AM ~08/30/09 12:10:10 PM ~08/27/10 08:16:21 PM ~ +09/01/10 12:12:12 AM INT~07/04/10 03:21:15 AM ~07/08/10 04:17:33 PM ~06/30/10 04:22:11 AM ~ +06/28/10 10:11:01 PM PTRED~06/19/10 09:19:55 PM ~04/25/10 07:39:22 PM ~09/16/10 10:34:24 AM + ~07/22/10 06:19:38 PM RED~04/29/10 12:10:59 AM ~04/20/10 02:13:33 AM ~07/17/10 01:00:05 PM ~ +09/01/10 11:10:15 PM INT~05/23/10 11:11:11 PM ~01/08/10 10:45:12 PM ~05/15/09 03:29:37 AM ~ +05/18/09 12:59:59 PM

It populates an array with the dates; sorts the indices of the array, by the (ascending) values of the dates indexed; then adds one to the ordered indices to produce your "ranking value".

It really should work, but it doesn't! It produces this output which is clearly wrong, but for reasons I do not (yet) understand:

c:\test>junk51 EVENT JIM BOB SAM JACK PTRED 3 4 2 1 RED 2 3 1 4 INT 4 3 1 2 PTRED 2 1 4 3 RED 2 1 3 4 INT 3 4 2 1

At first I thought that maybe Date_Cmp(), needed the dates to be pre-parsed, but that didn't fix it.

Then I thought that maybe D::M was getting confused by the 2 digit years, so I fixed that up, but no change either.

So then I thought that the (elusively documented) "flag" returned by Date_Cmp() might be incompatible with the expectations of sort, but that doesn't seem to be the case either.

This modified version:

#! perl -slw use warnings; use strict; use Data::Dumper; use Date::Manip; print scalar <DATA>; while (<DATA>) { chomp; my @dates = split '~'; my $label = shift @dates; my @parsed = map{ s[/(\d\d) ][/20$1 ]; ParseDate( $_ ) } @dates; my @order = map $_+1, sort{ my $res = Date_Cmp( $dates[ $a ], $dates[ $b ] ); print "$dates[ $a ] <-> $dates[ $b ] := $res"; $res; } 0 .. $#parsed; print join "\t", $label, @order; } __DATA__ EVENT JIM BOB SAM JACK PTRED~09/29/10 03:23:05 PM ~09/28/10 02:21:09 PM ~09/26/10 11:00:03 AM + ~09/27/10 09:33:41 PM RED~08/29/10 01:55:00 AM ~08/30/09 12:10:10 PM ~08/27/10 08:16:21 PM ~ +09/01/10 12:12:12 AM INT~07/04/10 03:21:15 AM ~07/08/10 04:17:33 PM ~06/30/10 04:22:11 AM ~ +06/28/10 10:11:01 PM PTRED~06/19/10 09:19:55 PM ~04/25/10 07:39:22 PM ~09/16/10 10:34:24 AM + ~07/22/10 06:19:38 PM RED~04/29/10 12:10:59 AM ~04/20/10 02:13:33 AM ~07/17/10 01:00:05 PM ~ +09/01/10 11:10:15 PM INT~05/23/10 11:11:11 PM ~01/08/10 10:45:12 PM ~05/15/09 03:29:37 AM ~ +05/18/09 12:59:59 PM

Produces this:

c:\test>junk51 EVENT JIM BOB SAM JACK 09/29/2010 03:23:05 PM <-> 09/28/2010 02:21:09 PM := 1 09/26/2010 11:00:03 AM <-> 09/27/2010 09:33:41 PM := -1 09/28/2010 02:21:09 PM <-> 09/26/2010 11:00:03 AM := 1 09/28/2010 02:21:09 PM <-> 09/27/2010 09:33:41 PM := 1 PTRED 3 4 2 1 08/29/2010 01:55:00 AM <-> 08/30/2009 12:10:10 PM := 1 08/27/2010 08:16:21 PM <-> 09/01/2010 12:12:12 AM := -1 08/30/2009 12:10:10 PM <-> 08/27/2010 08:16:21 PM := -1 08/27/2010 08:16:21 PM <-> 08/29/2010 01:55:00 AM := -1 08/29/2010 01:55:00 AM <-> 09/01/2010 12:12:12 AM := -1 RED 2 3 1 4 07/04/2010 03:21:15 AM <-> 07/08/2010 04:17:33 PM := -1 06/30/2010 04:22:11 AM <-> 06/28/2010 10:11:01 PM := 1 07/04/2010 03:21:15 AM <-> 06/28/2010 10:11:01 PM := 1 07/04/2010 03:21:15 AM <-> 06/30/2010 04:22:11 AM := 1 INT 4 3 1 2 06/19/2010 09:19:55 PM <-> 04/25/2010 07:39:22 PM := 1 09/16/2010 10:34:24 AM <-> 07/22/2010 06:19:38 PM := 1 04/25/2010 07:39:22 PM <-> 07/22/2010 06:19:38 PM := -1 07/22/2010 06:19:38 PM <-> 06/19/2010 09:19:55 PM := 1 PTRED 2 1 4 3 04/29/2010 12:10:59 AM <-> 04/20/2010 02:13:33 AM := 1 07/17/2010 01:00:05 PM <-> 09/01/2010 11:10:15 PM := -1 04/20/2010 02:13:33 AM <-> 07/17/2010 01:00:05 PM := -1 07/17/2010 01:00:05 PM <-> 04/29/2010 12:10:59 AM := 1 RED 2 1 3 4 05/23/2010 11:11:11 PM <-> 01/08/2010 10:45:12 PM := 1 05/15/2009 03:29:37 AM <-> 05/18/2009 12:59:59 PM := -1 01/08/2010 10:45:12 PM <-> 05/15/2009 03:29:37 AM := 1 01/08/2010 10:45:12 PM <-> 05/18/2009 12:59:59 PM := 1 INT 3 4 2 1

Each individual comparison produces the expected result, but still the ordering is wrong. For all teh world it looks like sort is making mistakes :)

At this point I ran out of ideas, so I throw it over to the monks to point out my mis deliberate error?


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".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Need help comparing 4 dates (sort errors?)
by AnomalousMonk (Archbishop) on Oct 03, 2010 at 08:53 UTC
    It populates an array with the dates; sorts the indices of the array, by the (ascending) values of the dates indexed; then adds one to the ordered indices to produce your "ranking value".

    But the 'ranking value' is really the date itself: the earliest date is 'first place', the latest date is 'fourth place' (in the OPed example data). It's necessary to convert each date, at some point, into its 'place' from 1 to n.

    Once the ordered dates have been converted to place values, they have to be restored to the original order of the 'players' Jim .. Jack for printing.

      Duh! Of course. Thanks.

      Once I've sorted the indices by the dates, in order to rank them; I need to sort the indices by that ranking to get them back into the original order:

      #! perl -slw use warnings; use strict; use Data::Dumper; use Date::Manip; print scalar <DATA>; while (<DATA>) { chomp; my @dates = split '~'; my $label = shift @dates; my @order = sort{ Date_Cmp( $dates[ $a ], $dates[ $b ] ); } 0 .. $#dates; print join "\t", $label, map $_+1, sort{ $order[ $a ] <=> $order[ $b ] } 0..$#order; } __DATA__ EVENT JIM BOB SAM JACK PTRED~09/29/10 03:23:05 PM ~09/28/10 02:21:09 PM ~09/26/10 11:00:03 AM + ~09/27/10 09:33:41 PM RED~08/29/10 01:55:00 AM ~08/30/09 12:10:10 PM ~08/27/10 08:16:21 PM ~ +09/01/10 12:12:12 AM INT~07/04/10 03:21:15 AM ~07/08/10 04:17:33 PM ~06/30/10 04:22:11 AM ~ +06/28/10 10:11:01 PM PTRED~06/19/10 09:19:55 PM ~04/25/10 07:39:22 PM ~09/16/10 10:34:24 AM + ~07/22/10 06:19:38 PM RED~04/29/10 12:10:59 AM ~04/20/10 02:13:33 AM ~07/17/10 01:00:05 PM ~ +09/01/10 11:10:15 PM INT~05/23/10 11:11:11 PM ~01/08/10 10:45:12 PM ~05/15/09 03:29:37 AM ~ +05/18/09 12:59:59 PM

      Produces:

      c:\test>junk51 EVENT JIM BOB SAM JACK PTRED 4 3 1 2 RED 3 1 2 4 INT 3 4 2 1 PTRED 2 1 4 3 RED 2 1 3 4 INT 4 3 1 2

      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".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Thank you so much! This is spot on!

        Hi All, this does work beautifully, except for one thing...i keep getting the following warning message:

        Use of uninitialized value in length at /u/capsftp/lib/perl5/site_perl/5.8.0/Date/Manip.pm line 247, <DATA> line 2

        I was curious if you were getting it also? and if so, any idea what is causing it? With Data::Dumper i can see the values all seem to be defined when passed to the Date_Cmp function so not sure why it's happening

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-03-19 07:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found