Re: Re: DT::Duration overloads

2004-06-11 Thread Rick Measham
I said:
On the other hand, maybe these should be DateTime::Set methods:
   my $mean   = $set-mean( $sunrise, $sunset );
   my $median = $set-median( $sunrise, $sunset );

On Thu, 10 Jun 2004 18:04:36 -0700, Bruce Van Allen wrote
 Huh? I'm confused by your usage of 'mean' and 'median'. In the case in
 question, I think 'midpoint' is a much clearer term to use.

I suggest placing mean and median in a module rather than just the FAQ because the 
current solution is just the midpoint of two datetimes. The mean can give this, but 
can 
also give results for more than two datetimes. 

Consider that an FAQ entry for calculating the average time you start work from a list 
of 
DateTimes would be a lot longer so should we put it in the FAQ? I don't think so. I 
think 
it should be a library method placed either in a Util module or in the DateTime::Set 
module. Then, once we do that, we can change the FAQ entry for midpoint to Either 
use the 'mean' function in DateTime::XXX::XXX or use the following algorithm

As for my usage of 'mean' and 'median':

'mean' and 'median' are mathematical constructs. The 'mean' is often called the 
'average' while the 'median' would be the middle value.

mean(1,2,3) == 2
median(1,2,3) == 2

But here's the difference:
mean(1,2,6) == 3
median(1,2,6) == 2

And the 'median' value with an even number of arguments:
median(1,2,3,4) == 2.5
(middle is both 2 and 3, therefore use their mean (2 + 3) / 2 == 2.5)


And the maths involved:
sub mean{
   return sum(@_) / scalar(@_);
}

sub median{
   my $middle = (scalar(@_) + 1) / 2;
   return ($middle == int(middle)) 
  ? $_[  $middle ]
  : mean( $_[  int($middle) ], $_[  int($middle)+1 ]);
}

sub sum {
   my $return = 0;
   $return += $_ foreach @_;
   return $return;
}

Of course, the DateTime code would be more difficult. I'd probably cheat by getting 
rd_secs and using the above mathematical functions to get mean and median rd_secs 
and then turning them back into DateTime objects.

Hope that clears it up.

Cheers!
Rick




Re: DT::Duration overloads

2004-06-11 Thread Matt Sisk
Quoting Dave Rolsky [EMAIL PROTECTED]:
  With DateTime::Span:
 
   $mid_point =
  $span-start-add_duration(
  seconds = $span-duration-seconds / 2
  );
 
  With DateTime:
 
$mid_point =
  $start-add_duration(
  seconds = $end-subtract_datetime_absolute(
  $start
  )-seconds / 2
  );

 Oh, duh!  Why didn't I think of that.  That's nice  simple.

If the operator overloads did that sort of thing behind the scene (and yes, with
spans also), then it would be nicer and simpler. :)

But thanks, Flavio and Dave, for the recipes and dealing with my questions.

  How about a DateTime::Span-midpoint method?

 Let's wait and see if others ask for it.  For now, let's just add those
 recipes to the faq.

Midpoints are compelling, but also arbitrary. I'd like to see the general
problem of portioning a span, or the delta between two arbitrary datetimes
(expressed as a span or otherwise, transparently), solved in a general way.
After all, if midpoint is that common, sure, provide a method, but we don't
need methods for thirds, quarters, eighths, forty-thirds, etc.

Thanks again,
Matt (in the Big Easy for a wedding...man I should get some sleep)

P.S. Sorry for the wonky quoting in my earlier messages -- I plead inadequate
mail client that can't properly convert between markup and plain text.



Re: DT::Duration overloads

2004-06-11 Thread Dave Rolsky
On Fri, 11 Jun 2004, Matt Sisk wrote:

 Quoting Dave Rolsky [EMAIL PROTECTED]:
   With DateTime::Span:
  
$mid_point =
   $span-start-add_duration(
   seconds = $span-duration-seconds / 2
   );
  
   With DateTime:
  
 $mid_point =
   $start-add_duration(
   seconds = $end-subtract_datetime_absolute(
   $start
   )-seconds / 2
   );
 
  Oh, duh!  Why didn't I think of that.  That's nice  simple.

 If the operator overloads did that sort of thing behind the scene (and yes, with
 spans also), then it would be nicer and simpler. :)

Uh, exactly what operator would you overload for DateTime?  I certainly
don't see and obvious candidate.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-10 Thread Dave Rolsky
On Thu, 10 Jun 2004, Matt Sisk wrote:

 What I'd like to do is simply find the midpoint, more or less, between
 two arbitrary datetimes. Off the cuff, knowing nothing about the
 internals (which I do, but I'm pretending not to) I'd think this:

   $mid = $dt1 + ($dt2 - $dt1)/2

 to dwim.

 However, as you say, things aren't really well defined the way durations
 are defined internally at the moment.

 So the question becomes -- if the above is not the datetime idiom for
 finding a midpoint between two datetimes, then what is?

Well, if you just want the _date_, it's pretty easy.

 my $dur = $dt1-delta_days($dt2);

 # or use Math::Round if you want
 my $mid = $dt1-add( days = int( $dur-delta_days / 2 ) );

If you want to account for the time then it gets funkier.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-10 Thread Dave Rolsky
On Thu, 10 Jun 2004, Matt Sisk wrote:

 What I'd like to do is simply find the midpoint, more or less, between
 two arbitrary datetimes. Off the cuff, knowing nothing about the
 internals (which I do, but I'm pretending not to) I'd think this:

Also, I'd like to point out that this really doesn't have as much to do
with the internals as it does with the nature of date  time math.

You cannot expect to understand date math without understanding that it's
not possible to convert between various units of date/time, in particular
from months to days or vice versa.  This would be a problem regardless of
the internals, right?


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-10 Thread Matt Sisk
Dave Rolsky wrote:
Well, if you just want the _date_, it's pretty easy.
my $dur = $dt1-delta_days($dt2);
# or use Math::Round if you want
my $mid = $dt1-add( days = int( $dur-delta_days / 2 ) );
If you want to account for the time then it gets funkier.
Hmm, indeed.
I need to approximate solar noon by deriving the midpoint between 
sunrise and sunset. I also need to approximate solar midnight by looking 
at the sunset from the prior day.

As a general problem, finding a fractional time between two points in 
time is not that unusual. I *suppose* I could convert to epoch, take the 
diff, and use that to create a new duration. But it seems unfortunate 
that I'd have to step out of the datetime API like that. The two 
endpoints are known quantities -- there is no abiguity in selecting a 
midpoint.

Is this sort of thing something that should exist in spans rather than 
expecting regular date math to handle?

Matt


Re: DT::Duration overloads

2004-06-10 Thread Matt Sisk
Dave Rolsky wrote:
Also, I'd like to point out that this really doesn't have as much to do
with the internals as it does with the nature of date  time math.
You cannot expect to understand date math without understanding that it's
not possible to convert between various units of date/time, in particular
from months to days or vice versa.  This would be a problem regardless of
the internals, right?
 

I do understand the ambiguities when you are dealing with various forms 
of durations that are not anchored to an actual point in time. As I said 
in my last message, however, we're talking about two absolute points in 
time -- no ambiguity.

Rephrased, the question is again: what is the midpoint of a span? (and 
if we come up with a good approach to this problem, it should solve the 
general class of problems having to do with portioning out spans).

It's not immediately apparent to me what the solution is -- I know what 
I want to do, and would prefer it to be fairly easy and straightforward. 
This seems to be an area of the interface that could use some brushing 
up rather than some intrinsic ambiguity of date math.

(I'm willing to meditate on possible solutions myself -- I'm not merely 
asking you to solve it for me. However, I just thought I might be 
missing something obvious)

Thanks again,
Matt


Re: DT::Duration overloads

2004-06-10 Thread fglock
Matt Sisk wrote:
 what is the midpoint of a span? 

With DateTime::Span:

 $mid_point = 
$span-start-add_duration(
seconds = $span-duration-seconds / 2 
);

With DateTime:

  $mid_point = 
$start-add_duration(
seconds = $end-subtract_datetime_absolute( 
$start 
)-seconds / 2 
);

(you may want to account for fractional
seconds too)

How about a DateTime::Span-midpoint method?

- Flavio S. Glock




Re: DT::Duration overloads

2004-06-10 Thread Dave Rolsky
On Thu, 10 Jun 2004 [EMAIL PROTECTED] wrote:

 Matt Sisk wrote:
  what is the midpoint of a span?

 With DateTime::Span:

  $mid_point =
 $span-start-add_duration(
 seconds = $span-duration-seconds / 2
 );

 With DateTime:

   $mid_point =
 $start-add_duration(
 seconds = $end-subtract_datetime_absolute(
 $start
 )-seconds / 2
 );

Oh, duh!  Why didn't I think of that.  That's nice  simple.

 How about a DateTime::Span-midpoint method?

Let's wait and see if others ask for it.  For now, let's just add those
recipes to the faq.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: Re: DT::Duration overloads

2004-06-10 Thread Rick Measham
On Thu, 10 Jun 2004 [EMAIL PROTECTED] wrote:
How about a DateTime::Span-midpoint method?
On 11 Jun 2004, at 6:55 AM, Dave Rolsky replied:
Let's wait and see if others ask for it.  For now, let's just add those
recipes to the faq.
I'm not sure of the best namespace, but I can see a Util namespace 
would be a good place for FRSs (Frequently Required Solutions)

use DateTime::Util::Stats qw/:all/;
# Solar Noon is the mean of sunrise and sunset:
my $mean   = mean_datetime( @dt_list )
# The mean is: round(scalar(@_) + 1 / 2) # IIRC
#   therefore $median == $sunset
my $median = median_datetime( @dt_list )
On the other hand, maybe these should be DateTime::Set methods:
my $mean   = $set-mean( $sunrise, $sunset );
my $median = $set-median( $sunrise, $sunset );
I'm not sure that DateTime::Span is a good place for these as it would 
only apply to getting the mean of two DateTime objects whereas in 
DateTime::Set it's scope increases to allow any number of DateTimes.

Would/Could there be any use for other statistical functions such as 
Standard Deviations? I can't think of any possible need for StdDev at 
the moment, but maybe there getting rid of outliers will be of benefit 
to someone?

Cheers!
Rick
Senior Developer
PrintSupply - Print Procurement  Supply Management
18 Greenaway Street VIC 3105
Tel: (03) 9850 3255
Fx: (03) 9850 3277
http://www.printsupply.com.au/


Re: Re: DT::Duration overloads

2004-06-10 Thread Bruce Van Allen
On 6/11/04 Rick Measham wrote:
On Thu, 10 Jun 2004 [EMAIL PROTECTED] wrote:
 How about a DateTime::Span-midpoint method?

On 11 Jun 2004, at 6:55 AM, Dave Rolsky replied:
 Let's wait and see if others ask for it.  For now, let's just
add those recipes to the faq.

I'm not sure of the best namespace, but I can see a Util namespace 
would be a good place for FRSs (Frequently Required Solutions)

Flavio's solutions are brief and efficient. Why not just have it in the
FAQ, as Dave suggests?

   use DateTime::Util::Stats qw/:all/;
   # Solar Noon is the mean of sunrise and sunset:
   my $mean   = mean_datetime( @dt_list )
   # The mean is: round(scalar(@_) + 1 / 2) # IIRC
   #   therefore $median == $sunset
   my $median = median_datetime( @dt_list )

On the other hand, maybe these should be DateTime::Set methods:
   my $mean   = $set-mean( $sunrise, $sunset );
   my $median = $set-median( $sunrise, $sunset );

Huh? I'm confused by your usage of 'mean' and 'median'. In the case in
question, I think 'midpoint' is a much clearer term to use.

My $.02.

1;

- Bruce

__bruce__van_allen__santa_cruz__ca__


DT::Duration overloads

2004-06-09 Thread Matt Sisk
I understand that division can be expressed as multiplication, but is 
there any particular reason why division (/) is not overloaded but 
multiplication is for durations? Then you could say:

 $midpoint = ($dt2 - $dt1)/2;
rather than
 $midpoint = ($dt2 - $dt1) * 0.5;
Small thing. Just curious.
Thanks,
Matt


Re: DT::Duration overloads

2004-06-09 Thread Dave Rolsky
On Wed, 9 Jun 2004, Matt Sisk wrote:

 I understand that division can be expressed as multiplication, but is
 there any particular reason why division (/) is not overloaded but
 multiplication is for durations? Then you could say:

   $midpoint = ($dt2 - $dt1)/2;

 rather than

   $midpoint = ($dt2 - $dt1) * 0.5;

 Small thing. Just curious.

Well, division doesn't really work, whether you do it as multiplication or
not ;)

What is half a minute?  How long is half a month?


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-09 Thread Rick Measham
On 10 Jun 2004, at 9:25 AM, Dave Rolsky wrote:
What is half a minute?  How long is half a month?
$dtd = DateTime::Duration-new(
months  = 1,
minutes = 1,
);
$half_dtd = $dtd / 2;
print $half_dtd-months . \n;
# 0.5
print $half_dtd-seconds . \n;
# 0.5
print strfduration(
	normalise = 'ISO',
	pattern   = '%Y years, %m months, %e days, %H hours, %M minutes, %S 
seconds',
	duration  = $half_dtd
);
# 0 years, 0 months, 15 days, 0 hours, 0 minutes, 30 seconds


Senior Developer
PrintSupply - Print Procurement  Supply Management
18 Greenaway Street VIC 3105
Tel: (03) 9850 3255
Fx: (03) 9850 3277
http://www.printsupply.com.au/


Re: DT::Duration overloads

2004-06-09 Thread Dave Rolsky
On Thu, 10 Jun 2004, Rick Measham wrote:

 On 10 Jun 2004, at 9:25 AM, Dave Rolsky wrote:
  What is half a minute?  How long is half a month?

 $dtd = DateTime::Duration-new(
   months  = 1,
   minutes = 1,
 );

 $half_dtd = $dtd / 2;

 print $half_dtd-months . \n;
 # 0.5

 print $half_dtd-seconds . \n;
 # 0.5

 print strfduration(
   normalise = 'ISO',
   pattern   = '%Y years, %m months, %e days, %H hours, %M minutes, %S
 seconds',
   duration  = $half_dtd
 );
 # 0 years, 0 months, 15 days, 0 hours, 0 minutes, 30 seconds

Great, now what should DateTime.pm do in the add_duration method?


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-09 Thread Dave Rolsky
On Wed, 9 Jun 2004, Matt Sisk wrote:

 I understand that division can be expressed as multiplication, but is
 there any particular reason why division (/) is not overloaded but
 multiplication is for durations? Then you could say:

   $midpoint = ($dt2 - $dt1)/2;

 rather than

   $midpoint = ($dt2 - $dt1) * 0.5;

 Small thing. Just curious.

Thinking about this more, I'm considering maybe just requiring that
multiplication be passed an integer, because if you do this:

 my $dur = DateTime::Duration-new( months = 1, days = 1, minutes = 1 );
 $dur-multiple(.5);

 print DateTime-now-add_duration($dur)-datetime;

The results are kind of weird, and certainly not what anyone would expect.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/


Re: DT::Duration overloads

2004-06-09 Thread Matt Sisk
Dave Rolsky wrote:
Thinking about this more, I'm considering maybe just requiring that
multiplication be passed an integer, because if you do this:
 

What I'd like to do is simply find the midpoint, more or less, between 
two arbitrary datetimes. Off the cuff, knowing nothing about the 
internals (which I do, but I'm pretending not to) I'd think this:

 $mid = $dt1 + ($dt2 - $dt1)/2
to dwim.
However, as you say, things aren't really well defined the way durations 
are defined internally at the moment.

So the question becomes -- if the above is not the datetime idiom for 
finding a midpoint between two datetimes, then what is?

Thanks,
Matt