Off Topic Advice Needed (Time objects)

I know this is a Ruby question but I’m not on any Ruby mailing lists and
it’s for a Rails project (so might come under select_time etc. :wink: ) I
thought I’d try here.

A user can choose integer values from select drop down boxes to predict
how
long an event will take. Obvious values are secs (0-59), minutes (0-59)

weeks (0-4), months (0-11) …

These values are then converted to seconds and stored as decimal in the
DB
(I allow fractions of a second, too (tenth, hundredth, millisecond).
when
they are retrieved form the DB, I convert the seconds to a string format
of,
for example, 01:39:11 (from 5951 seconds). If fractions are used, they
are
just appended to the string. (non of this is elegant IMO)

That’s all done in my Converter class. I am going to write a Calculator
class to compare all times entered for an event and picking the closest
times to how long the actual event took.

So my question is, I know I can’t use a Time object but it would be
really
nice to know if there is something out there that could help me with
this as
to write my own Calculator is going to be a bit of a pain.

Also, by throwing this out there, somebody might say something that I
haven’t thought of doing and could totally change the way I’m doing
this.

CIA

-Ants

So my question is, I know I can’t use a Time object but it would be really
nice to know if there is something out there that could help me with this as
to write my own Calculator is going to be a bit of a pain.

If you have two floating point values representing seconds (and parts
of)
why can’t you just compare the two floating point values?

What part are you stuck with? Can you give us some code with a comment
on
which bit you can’t do.

Andy

On 16 June 2010 15:54, Andy J. [email protected] wrote:

So my question is, I know I can’t use a Time object but it would be really

http://groups.google.com/group/rubyonrails-talk?hl=en.

I don’t have a problem with comparing floats, but I might need to find
the
10 closest times to the actual event time and 4 of those times could be
less
than the actual event time and 6 could be higher.

I don’t mind rolling my own and am quite looking forward to it, but I
don’t
want to re-invent the proverbial wheel.

FWIW, here’s the conversion code to convert integer values to their
respective seconds.

@@time_constants = {:years => YEAR,
  :months => MONTH,
  :weeks => WEEK,
  :days => DAY,
  :hours => HOUR,
  :mins => MIN  }

def to_decimal(time_units={})
  raise ArgumentError if time_units.empty?

  time_units.each_pair do |key, value|
    ## skip seconds and fractions thereof
    next unless @@time_constants.has_key?(key)
    ## convert integer time units into seconds
    @decimal_time += @@time_constants[key] * value
  end
  ## whack on the seconds
  @decimal_time += time_units[:secs] if time_units.has_key?(:secs)

  ## need validation (can't have hundtedth without tenth, for 

example)
fraction = ‘’
fraction = ‘.’ + time_units[:tenth].to_s if
time_units.has_key?(:tenth)
fraction << time_units[:hundredth].to_s if
time_units.has_key?(:hundredth)
fraction << time_units[:millisecond].to_s if
time_units.has_key?(:millisecond)

  ## concat fraction string to @decimal_time, convert to float for 

DB
@decimal_time = (@decimal_time.to_s << fraction).to_f
end

On 16 June 2010 15:51, Ants P. [email protected] wrote:

I don’t have a problem with comparing floats, but I might need to find the
10 closest times to the actual event time and 4 of those times could be less
than the actual event time and 6 could be higher.

As a starting point, IIWM I would:

  • Get the ten times either side (so I have twenty objects).
  • Calculate the difference of how far each is from the event (ignoring
    sign)
  • Order the twenty by the difference
  • Take the first ten of them.

With a bit of thought this could all be done in SQL… possibly with a
couple of sub-queries. But it could certainly be stepped through in
Ruby very easily.

than the actual event time and 6 could be higher.

I don’t mind rolling my own and am quite looking forward to it, but I don’t
want to re-invent the proverbial wheel.

This seems a fairly simple wheel to be worried about re-inventing though
(or
even to look forward to).

OK, so you have an array of times. You sort through them based on:

(predicted_time - actual_time).abs

and pick the smallest 10 items.

Cheers,

Andy

On 16 June 2010 16:57, Michael P. [email protected] wrote:

sign)
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected][email protected]
.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

As I have said before, I have no problems with all of that but thanks
for
the suggestions. Things do get a bit more complicated with the
Calculator,
though and I was only looking to make sure I wasn’t wasting my time when
there was something already out there.

I’ll just press on. Again, thanks for your time.

On 16 June 2010 18:07, Michael P. [email protected] wrote:

http://snippets.dzone.com/posts/show/1137

Of course, ignore me if there’s some critical reason they must be
http://groups.google.com/group/rubyonrails-talk?hl=en.

Not to worry about this as I’m happy where I’m going. Logically it’s not
a
huge problem, getting it Rubyish might be :wink: Long time Perl programmer.

Thanks for the links, I’d already seen the second link.

Thanks for the bit about the fractions, it’s given me something to think
about but from what I can see, they will still have to be tacked on to
the
decimal. The decimals were done the way you suggested but now they’re
just
in a loop (more flexible) as time_units may well be added in the future.

I don’t want to labour on this so I’ll just do what I was going to do.
Again, thanks.

On 16 June 2010 16:45, Ants P. [email protected] wrote:

As I have said before, I have no problems with all of that but thanks for
the suggestions.

To be honest, I don’t really understand what you’re asking for help
with. If you can state your position in different terms, because what
you’ve said so far obviously hasn’t clicked with anyone (or at least
we’ve clicked the same, wrong, way! :wink:

Feeling around in the dark a little:
http://snippets.dzone.com/posts/show/1137
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/170729

The code you posted does look a little smelly. I don’t know why you’re
turning your numbers into strings and then back into numbers again.
For instance, where you say " ## need validation (can’t have hundtedth
without tenth, for example)", I think you could ignore if you just
approach adding up the seconds differently.

So for instance if :
time_units = {:seconds => 22, :hundredths => 0, :milliseconds => 8}

you can just do the arithmetic:

fraction = 0
fraction += time_units[:tenths] * .1 if time_units.has_key?(:tenths)
fraction += time_units[:hundredths] * .01 if
time_units.has_key?(:hundredths)
fraction += time_units[:milliseconds] *.001 if
time_units.has_key?(:milliseconds)

should result in 0.008

Frankly, stuff the fraction variable. Treat @decimal_time the same:
@decimal_time += time_units[:seconds] if time_units.has_key?(:seconds)
@decimal_time += time_units[:minutes] * 60 if
time_units.has_key?(:minutes)
@decimal_time += time_units[:hours] * 3600 if
time_units.has_key?(:hours)
@decimal_time += time_units[:milliseconds] *.001 if
time_units.has_key?(:milliseconds)
etc…

Of course, ignore me if there’s some critical reason they must be
strings! :slight_smile:

Ants P. wrote:

I know this is a Ruby question but I’m not on any Ruby mailing lists

Then get on one (perhaps ruby-talk) and ask there. Don’t make lazy
excuses for asking off-topic questions.

and
it’s for a Rails project (so might come under select_time etc. :wink: )

That may be a better reason to ask here.

I
thought I’d try here.

I’ll look at your question when I have a little more time, but please
remember that “because I couldn’t bother to join the appropriate list”
is not a valid reason for posting off-topic questions. :slight_smile:

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]