[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [QUIZ] Time Window (#144

James Koppel

10/24/2007 1:05:00 AM

Here's my solution. It converts a time window into an array of arrays of ranges. Each range matches an interval of time (e.g.: 500..1700); each subarray contains all the ranges for a given day. I then wrote the simple Array#some method that returns true if the given predicate returns true for at least one of its elements, which I used to write TimeWindow#incude?.$days = {"Sun"=>0, "Mon"=>1, "Tue"=>2, "Wed"=>3, "Thu"=>4, "Fri"=>5, "Sat"=>6}class Array def some each {|el| return true if yield el} false endendclass TimeWindow def initialize(win_str) @times = ([nil]*7).map{[]} win_str << " " #In case of empty win_str.split(/;/).each do |win| days_str = win.match(/(((#{$days.keys.join('|')}|)( |-)?)*)/)[0]..strip days = [] days_str.scan(/#{$days.keys.join('|')}/) do |day| days << $days[day] end days_str.scan(/(#{$days.keys.join('|')})-(#{$days.keys.join('|')})/) do a = $days[$1] b = $days[$2] days += (a..(b > a ? b : b+7))..to_a.map{|d|d%7} end days = (0..6).to_a if days.empty? times = [] win.scan(/(\d{4})-(\d{4})/) do times << (($1.to_i)...($2.to_i)) end times = [0..2400] if times.empty? days.each do |d| times.each do |t| @times[d] << t end end end def include?(time) @times[time.wday].some{|trange| trange === (time.hour*100+time.min)} end endend----- Original Message ----From: Ruby Quiz <james@grayproductions.net>To: ruby-talk ML <ruby-talk@ruby-lang.org>Sent: Friday, October 19, 2007 7:14:00 AMSubject: [QUIZ] Time Window (#144)The three rules of Ruby Quiz:1. Please do not post any solutions or spoiler discussion for this quiz until48 hours have passed from the time on this message.2.. Support Ruby Quiz by submitting ideas as often as you can:http://www.ruby.... Enjoy!Suggestion: A [QUIZ] in the subject of emails about the problem helps everyoneon Ruby Talk follow the discussion. Please reply to the original quiz message,if you can.-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=by Brian CandlerWrite a Ruby class which can tell you whether the current time (or any giventime) is within a particular "time window". Time windows are defined by stringsin the following format: # 0700-0900 # every day between these times # Sat Sun # all day Sat and Sun, no other times # Sat Sun 0700-0900 # 0700-0900 on Sat and Sun only # Mon-Fri 0700-0900 # 0700-0900 on Monday to Friday only # Mon-Fri 0700-0900; Sat Sun # ditto plus all day Sat and Sun # Fri-Mon 0700-0900 # 0700-0900 on Fri Sat Sun Mon # Sat 0700-0800; Sun 0800-0900 # 0700-0800 on Sat, plus 0800-0900 on SunTime ranges should exclude the upper bound, i.e. 0700-0900 is 07:00:00 to08:59:59. An empty time window means "all times everyday". Here are some testcases to make it clearer: class TestTimeWindow < Test::Unit::TestCase def test_window_1 w = TimeWindow.new("Sat-Sun; Mon Wed 0700-0900; Thu 0700-0900 1000-1200") assert ! w.include?(Time.mktime(2007,9,25,8,0,0)) # Tue assert w.include?(Time.mktime(2007,9,26,8,0,0)) # Wed assert ! w.include?(Time.mktime(2007,9,26,11,0,0)) assert ! w.include?(Time.mktime(2007,9,27,6,59,59)) # Thu assert w.include?(Time.mktime(2007,9,27,7,0,0)) assert w.include?(Time.mktime(2007,9,27,8,59,59)) assert ! w.include?(Time.mktime(2007,9,27,9,0,0)) assert w.include?(Time.mktime(2007,9,27,11,0,0)) assert w.include?(Time.mktime(2007,9,29,11,0,0)) # Sat assert w.include?(Time.mktime(2007,9,29,0,0,0)) assert w.include?(Time.mktime(2007,9,29,23,59,59)) end def test_window_2 w = TimeWindow.new("Fri-Mon") assert ! w.include?(Time.mktime(2007,9,27)) # Thu assert w.include?(Time.mktime(2007,9,28)) assert w.include?(Time.mktime(2007,9,29)) assert w.include?(Time.mktime(2007,9,30)) assert w.include?(Time.mktime(2007,10,1)) assert ! w.include?(Time.mktime(2007,10,2)) # Tue end def test_window_nil w = RDS::TimeWindow.new("") assert w.include?(Time.mktime(2007,9,25,1,2,3)) # all times end end__________________________________________________Do You Yahoo!?Tired of spam? Yahoo! Mail has the best spam protection around http://mail...


8 Answers

Jesús Gabriel y Galán

10/24/2007 7:17:00 AM

0

On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote:
> I then wrote the simple Array#some method that returns true if the given
> predicate returns true for at least one of its elements, which I used to write
> TimeWindow#incude?.

> class Array
> def some
> each {|el| return true if yield el}
> false
> end
> end

Isn't this the same as Enumerable#any?

Jesus.

Philip Gatt

10/24/2007 8:04:00 AM

0

That's the same thought that I had. Assuming that any? didn't exist,
I am still fearful of adding methods to core classes. I think core
classes should only be modified in special cases, like building a
framework.

How do the rest of us feel about this?

- Philip

On Oct 24, 2007, at 12:16 AM, Jesús Gabriel y Galán wrote:

> On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote:
>> I then wrote the simple Array#some method that returns true if
>> the given
>> predicate returns true for at least one of its elements, which I
>> used to write
>> TimeWindow#incude?.
>
>> class Array
>> def some
>> each {|el| return true if yield el}
>> false
>> end
>> end
>
> Isn't this the same as Enumerable#any?
>
> Jesus.
>


Jesús Gabriel y Galán

10/24/2007 8:24:00 AM

0

On 10/24/07, Philip Gatt <gattster@gmail.com> wrote:
> That's the same thought that I had. Assuming that any? didn't exist,
> I am still fearful of adding methods to core classes. I think core
> classes should only be modified in special cases, like building a
> framework.
>
> How do the rest of us feel about this?

Well, first of all it depends if you are building a library that
someone will use, or just a program that will run independently. If
it's the former, even then I would think that just adding methods is
OK, as long as the method makes sense. What should be done with really
great care (or not at all) is modifying existing methods. But I'm
fairly new to Ruby so take my opinion with a grain of salt.

Jesus.

James Gray

10/24/2007 12:15:00 PM

0

On Oct 24, 2007, at 2:16 AM, Jesús Gabriel y Galán wrote:

> On 10/24/07, James Koppel <jamesbkoppel@yahoo.com> wrote:
>> I then wrote the simple Array#some method that returns true if
>> the given
>> predicate returns true for at least one of its elements, which I
>> used to write
>> TimeWindow#incude?.
>
>> class Array
>> def some
>> each {|el| return true if yield el}
>> false
>> end
>> end
>
> Isn't this the same as Enumerable#any?

It sure is.

James Edward Gray II

James Gray

10/24/2007 12:18:00 PM

0

On Oct 24, 2007, at 3:04 AM, Philip Gatt wrote:

> That's the same thought that I had. Assuming that any? didn't
> exist, I am still fearful of adding methods to core classes. I
> think core classes should only be modified in special cases, like
> building a framework.
>
> How do the rest of us feel about this?

Like most things, it's just another tool in your belt. You'll need
to consider when to use it and when not to.

On the plus side, slowly transforming Ruby into the language of a
problem is a powerful way to work. The minus is that you can make it
hard to use your code with other Ruby solutions in the process.

You will need to decide when that's a good trade-off and when it's
not. Ruby trusts you to make the choice.

James Edward Gray II

Ken Bloom

10/24/2007 2:08:00 PM

0

On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote:

> Here's my solution. It converts a time window into an array of arrays of
> ranges. Each range matches an interval of time (e.g.: 500..1700); each
> subarray contains all the ranges for a given day. I then wrote the
> simple Array#some method that returns true if the given predicate
> returns true for at least one of its elements, which I used to write
> TimeWindow#incude?.
>
> $days = {"Sun"=>0,
> "Mon"=>1,
> "Tue"=>2,
> "Wed"=>3,
> "Thu"=>4,
> "Fri"=>5,
> "Sat"=>6}

I suggest using a constant rather than a global variable for this. You
can put the constant in the TimeWindow class.

> class Array
> def some
> each {|el| return true if yield el}
> false
> end
> end

This has already been discussed as being equal to Enumerable#any?

> class TimeWindow
> def initialize(win_str)
> @times = ([nil]*7).map{[]}

This is the same as Array.new(7){[]}, which is a more usual way to
express this.

> win_str << " " #In case of empty
> win_str.split(/;/).each do |win|
> days_str = win.match(/(((#{$days.keys.join('|')}|)(
> |-)?)*)/)[0].strip days = []
> days_str.scan(/#{$days.keys.join('|')}/) do |day|
> days << $days[day]
> end
> days_str.scan(/(#{$days.keys.join('|')})-(#{$days.keys.join
('|')})/)
> do
> a = $days[$1]
> b = $days[$2]
> days += (a..(b > a ? b : b+7)).to_a.map{|d|d%7}
> end
> days = (0..6).to_a if days.empty?
>
> times = []
> win.scan(/(\d{4})-(\d{4})/) do
> times << (($1.to_i)...($2.to_i))
> end
> times = [0..2400] if times.empty?
>
> days.each do |d|
> times.each do |t|
> @times[d] << t
> end
> end
> end
>
> def include?(time)
> @times[time.wday].some{|trange| trange ===
> (time.hour*100+time.min)}
> end
> end
> end

Looks generally like my solution.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

James Gray

10/24/2007 2:16:00 PM

0

On Oct 24, 2007, at 9:10 AM, Ken Bloom wrote:

> On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote:
>
>> Here's my solution. It converts a time window into an array of
>> arrays of
>> ranges. Each range matches an interval of time (e.g.: 500..1700);
>> each
>> subarray contains all the ranges for a given day. I then wrote the
>> simple Array#some method that returns true if the given predicate
>> returns true for at least one of its elements, which I used to write
>> TimeWindow#incude?.
>>
>> $days = {"Sun"=>0,
>> "Mon"=>1,
>> "Tue"=>2,
>> "Wed"=>3,
>> "Thu"=>4,
>> "Fri"=>5,
>> "Sat"=>6}
>
> I suggest using a constant rather than a global variable for this. You
> can put the constant in the TimeWindow class.

This is also just an Array disguised as a Hash.

James Edward Gray II


Yossef Mendelssohn

10/25/2007 2:26:00 AM

0



On Oct 24, 9:16 am, James Edward Gray II <ja...@grayproductions.net>
wrote:
> On Oct 24, 2007, at 9:10 AM, Ken Bloom wrote:
>
>
>
> > On Wed, 24 Oct 2007 10:04:56 +0900, James Koppel wrote:
>
> >> Here's my solution. It converts atimewindowinto an array of
> >> arrays of
> >> ranges. Each range matches an interval oftime(e.g.: 500..1700);
> >> each
> >> subarray contains all the ranges for a given day. I then wrote the
> >> simple Array#some method that returns true if the given predicate
> >> returns true for at least one of its elements, which I used to write
> >> TimeWindow#incude?.
>
> >> $days = {"Sun"=>0,
> >> "Mon"=>1,
> >> "Tue"=>2,
> >> "Wed"=>3,
> >> "Thu"=>4,
> >> "Fri"=>5,
> >> "Sat"=>6}
>
> > I suggest using a constant rather than a global variable for this. You
> > can put the constant in the TimeWindow class.
>
> This is also just an Array disguised as a Hash.
>
> James Edward Gray II

It could be a lot worse. Which of us hasn't run across something like
this?

days = {
0 => 'Sun',
1 => 'Mon',
2 => 'Tue',
3 => 'Wed',
4 => 'Thu',
5 => 'Fri',
6 => 'Sat',
}

--
-yossef