Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [SOLUTION] Secret Santas (#2)

Reply
Thread Tools

[SOLUTION] Secret Santas (#2)

 
 
Ara.T.Howard
Guest
Posts: n/a
 
      10-04-2004

this solution parses stdin or an input file. the input may contain blank line
and comments. the input is first hashed last name -> first name -> email
using the Family class. next a Family::GiftPool for the current state of the
Family class is created and all families and their members iterated over; the
pool's 'draw_name' method randomly choses a santa not in the same family and
not the same person - the selection is destructive, meaning after someone has
been chosen they can no longer be chosen again. this method requires one pass
over the data (not counting the copy) and no sorting. mailing also included.



#!/usr/bin/env ruby
require 'net/smtp'

class EmailList < Array
#{{{
def initialize port
#{{{
buf =
if port.respond_to? 'read'
port.read
else
"#{ port }"
end
parse_buf buf
#}}}
end
def parse_buf buf
#{{{
buf.each do |line|
line.gsub! %r/^\s*|\s*$|#.*$/, ''
next if line.empty?
name, address = line.split %r/[<>]/
raise "syntax error in <#{ line }>" unless
name and address
tokens = name.strip.split %r/\s+/
last, first = tokens.pop, tokens.join(' ')
name = [first, last]
self << [name, address]
end
#}}}
end
#}}}
end
class Family < Hash
#{{{
class << self
#{{{
def families last = nil
#{{{
@families ||= {}
if last
@families[last] ||=
Hash::new{|h,last| h[last] ||= Family::new}
else
@families
end
#}}}
end
alias [] families
def each(*a, &b); families.each(*a, &b); end
def gift_pool; GiftPool::new families; end
#}}}
end
class GiftPool
#{{{
def initialize families
#{{{
@pool = Hash::new{|h,k| h[k] = Hash::new}
families.each do |last, members|
members.each do |first, email|
@pool[last][first] = email
end
end
#}}}
end
def draw_name last, first
#{{{
not_in_family = @pool.keys - [last]
family = not_in_family[rand(not_in_family.size)]

members = @pool[family].keys - [first]
member = members[rand(members.size)]

name = [family, member]
email = @pool[family][member]
santa = [name, email]

@pool[family].delete member
@pool.delete family if @pool[family].empty?

santa
#}}}
end
#}}}
end
#}}}
end
module Mailer
#{{{
def self.mail msg, to, from, opts = {}
#{{{
Net::SMTP.start('localhost') do |smtp|
email = ''
opts.each do |k, v|
email << "#{ k.capitalize }: #{ v }\r\n"
end
email << "\r\n#{ msg }"
smtp.send_message email, from, to
end
#}}}
end
#}}}
end


port = (ARGV.empty? ? STDIN : open(ARGV.shift))

list = EmailList::new port

list.each do |name, email|
Family[name.last][name.first] = email
end

gift_pool = Family.gift_pool

Family.each do |last, members|
members.each do |first, email|
santa = gift_pool.draw_name last, first
sname, semail = santa
msg = "you are the secret santa for <#{ sname.join ', ' }>"
Mailer::mail msg, email, nil, 'subject' => 'secret santa'
end
end


-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
 
 
 
Brian Schröder
Guest
Posts: n/a
 
      10-04-2004
Ara.T.Howard wrote:

> class EmailList < Array
> #{{{
> [snip]
> #}}}
> end


hello Ara,

Just out of interest, please do not understand this as an offence:
to which end are you using all those #{{{ comments? Is it to make your
editor understand indentation, or what is its purpose?

Regards,

Brian
--
Brian Schröder
http://ruby.brian-schroeder.de/


 
Reply With Quote
 
 
 
 
Ara.T.Howard@noaa.gov
Guest
Posts: n/a
 
      10-04-2004
On Tue, 5 Oct 2004, [ISO-8859-1] Brian Schröder wrote:

> Ara.T.Howard wrote:
>
>> class EmailList < Array
>> #{{{
>> [snip]
>> #}}}
>> end

>
> hello Ara,
>
> Just out of interest, please do not understand this as an offence:
> to which end are you using all those #{{{ comments? Is it to make your
> editor understand indentation, or what is its purpose?


vim is a folding editor. everything inbetween the markers appear as one line
as something like

+-- 3 lines: >> --------------------------------------------

in otherwords each class in my solution looks, to me, as

class Foo
+-- n lines: >> ------------
end

and each method likewise. if you don't use folding i highly reccomend it -
folds can be cut, pasted, operated on, etc. and, of course, it makes 10,000
source file a breeze to navigate.

cheers.

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
Anders Engström
Guest
Posts: n/a
 
      10-04-2004
On Tue, Oct 05, 2004 at 05:04:52AM +0900, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> On Tue, 5 Oct 2004, [ISO-8859-1] Brian Schröder wrote:
>
> >Ara.T.Howard wrote:
> >
> >>class EmailList < Array
> >>#{{{
> >> [snip]
> >>#}}}
> >>end

> >
> >hello Ara,
> >
> >Just out of interest, please do not understand this as an offence:
> >to which end are you using all those #{{{ comments? Is it to make your
> >editor understand indentation, or what is its purpose?

>
> vim is a folding editor. everything inbetween the markers appear as one
> line
> as something like
>
> +-- 3 lines: >> --------------------------------------------
>
> in otherwords each class in my solution looks, to me, as
>
> class Foo
> +-- n lines: >> ------------
> end
>
> and each method likewise. if you don't use folding i highly reccomend it -
> folds can be cut, pasted, operated on, etc. and, of course, it makes 10,000
> source file a breeze to navigate.
>


That's neat. Would you care to share the relevant lines from your
vimrc?

Best Regards //Anders

--
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Anders Engström (E-Mail Removed)
http://www.gnejs.net PGP-Key: ED010E7F
[Your mind is like an umbrella. It doesn't work unless you open it.]




 
Reply With Quote
 
Brian Schröder
Guest
Posts: n/a
 
      10-04-2004
(E-Mail Removed) wrote:
> On Tue, 5 Oct 2004, [ISO-8859-1] Brian Schr�der wrote:
>
>> Ara.T.Howard wrote:
>>
>>> class EmailList < Array
>>> #{{{
>>> [snip]
>>> #}}}
>>> end

>>
>>
>> hello Ara,
>>
>> Just out of interest, please do not understand this as an offence:
>> to which end are you using all those #{{{ comments? Is it to make your
>> editor understand indentation, or what is its purpose?

>
>
> vim is a folding editor. everything inbetween the markers appear as one
> line
> as something like
>
> +-- 3 lines: >> --------------------------------------------
>
> in otherwords each class in my solution looks, to me, as
>
> class Foo
> +-- n lines: >> ------------
> end
>
> and each method likewise. if you don't use folding i highly reccomend it -
> folds can be cut, pasted, operated on, etc. and, of course, it makes
> 10,000
> source file a breeze to navigate.
>
> cheers.
>
> -a
> --
> ================================================== =============================
>
> | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
> | PHONE :: 303.497.6469
> | A flower falls, even though we love it;
> | and a weed grows, even though we do not love it. | --Dogen
> ================================================== =============================

Ahh,

thanks for the pointer. I found the same for xemacs. But I think I
personally like hide-show better. Entering this additional comments seem
like too much work to me.

Regards,

Brian

--
Brian Schröder
http://ruby.brian-schroeder.de/


 
Reply With Quote
 
Ara.T.Howard@noaa.gov
Guest
Posts: n/a
 
      10-04-2004
On Tue, 5 Oct 2004, Anders [iso-8859-1] Engström wrote:

> That's neat. Would you care to share the relevant lines from your
> vimrc?


set foldmethod=marker
set commentstring=#%s

to use: highlight visually using 'shift-v' and motion keys then type

z-f -> fold create
z-o -> fold open
z-c -> fold close
z-d -> fold delete

all the fold command start with z because it looks like a fold

if you add those settings and open my script you'll see how it works quickly -
because the folds are marked they come up folded.

cheers.

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
Ara.T.Howard@noaa.gov
Guest
Posts: n/a
 
      10-04-2004
On Tue, 5 Oct 2004, [UTF-8] Brian Schröder wrote:

> thanks for the pointer. I found the same for xemacs. But I think I
> personally like hide-show better. Entering this additional comments seem
> like too much work to me.


but then they are lost when you close the file... if they are 'marked' they
are restored on open.

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
Gavin Sinclair
Guest
Posts: n/a
 
      10-05-2004
On Tuesday, October 5, 2004, 7:44:53 AM, Ara wrote:

> On Tue, 5 Oct 2004, [UTF-8] Brian Schröder wrote:


>> thanks for the pointer. I found the same for xemacs. But I think I
>> personally like hide-show better. Entering this additional comments seem
>> like too much work to me.


> but then they are lost when you close the file... if they are 'marked' they
> are restored on open.


Isn't it possible to fold based on syntax/indentation, thus getting
automatic Ruby folding without special markers?

Gavin




 
Reply With Quote
 
Ara.T.Howard@noaa.gov
Guest
Posts: n/a
 
      10-05-2004
On Tue, 5 Oct 2004, Gavin Sinclair wrote:

> On Tuesday, October 5, 2004, 7:44:53 AM, Ara wrote:
>
>> On Tue, 5 Oct 2004, [UTF-8] Brian Schröder wrote:

>
>>> thanks for the pointer. I found the same for xemacs. But I think I
>>> personally like hide-show better. Entering this additional comments seem
>>> like too much work to me.

>
>> but then they are lost when you close the file... if they are 'marked' they
>> are restored on open.

>
> Isn't it possible to fold based on syntax/indentation, thus getting
> automatic Ruby folding without special markers?


set foldmethod=syntax

it folds like mad though.

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
Gavin Sinclair
Guest
Posts: n/a
 
      10-05-2004
On Tuesday, October 5, 2004, 10:44:51 AM, Ara wrote:

> On Tue, 5 Oct 2004, Gavin Sinclair wrote:


>> On Tuesday, October 5, 2004, 7:44:53 AM, Ara wrote:
>>
>>> On Tue, 5 Oct 2004, [UTF-8] Brian Schröder wrote:

>>
>>>> thanks for the pointer. I found the same for xemacs. But I think I
>>>> personally like hide-show better. Entering this additional comments seem
>>>> like too much work to me.

>>
>>> but then they are lost when you close the file... if they are 'marked' they
>>> are restored on open.

>>
>> Isn't it possible to fold based on syntax/indentation, thus getting
>> automatic Ruby folding without special markers?


> set foldmethod=syntax


> it folds like mad though.


Can you impose limits on the madness?

Gavin





 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
OT: a secret. I have a secret. I have a secret. I won't tell you. Nanannannanana. Psychometrically Validated MCSE 13 02-22-2006 03:29 AM
[SUMMARY] Secret Santas (#2) Ruby Quiz Ruby 0 10-07-2004 01:00 PM
[SOLUTION] Secret Santas (#2) Peter McMaster Ruby 0 10-06-2004 12:04 AM
[SOLUTION] Secret Santas (#2) Peter McMaster Ruby 0 10-05-2004 11:17 PM
[QUIZ] Secret Santas (#2) Ruby Quiz Ruby 54 10-05-2004 07:54 PM



Advertisments