[SOLUTION] Secret Santas (#2)

Discussion in 'Ruby' started by Ara.T.Howard, Oct 4, 2004.

  1. Ara.T.Howard

    Ara.T.Howard Guest

    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
    ===============================================================================
    Ara.T.Howard, Oct 4, 2004
    #1
    1. Advertising

  2. [OT] Re: [SOLUTION] Secret Santas (#2)

    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/
    Brian Schröder, Oct 4, 2004
    #2
    1. Advertising

  3. Ara.T.Howard

    Guest

    Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    ===============================================================================
    , Oct 4, 2004
    #3
  4. Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    On Tue, Oct 05, 2004 at 05:04:52AM +0900, 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
    http://www.gnejs.net PGP-Key: ED010E7F
    [Your mind is like an umbrella. It doesn't work unless you open it.]
    Anders Engström, Oct 4, 2004
    #4
  5. Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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/
    Brian Schröder, Oct 4, 2004
    #5
  6. Ara.T.Howard

    Guest

    Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    ===============================================================================
    , Oct 4, 2004
    #6
  7. Ara.T.Howard

    Guest

    Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    ===============================================================================
    , Oct 4, 2004
    #7
  8. Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    Gavin Sinclair, Oct 5, 2004
    #8
  9. Ara.T.Howard

    Guest

    Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    ===============================================================================
    , Oct 5, 2004
    #9
  10. Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    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
    Gavin Sinclair, Oct 5, 2004
    #10
  11. Ara.T.Howard

    Guest

    Re: [OT] Re: [SOLUTION] Secret Santas (#2)

    On Tue, 5 Oct 2004, Gavin Sinclair wrote:

    > 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?


    set foldlevel=n

    -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
    ===============================================================================
    , Oct 5, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. et

    What's the secret?

    et, Nov 13, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    949
  2. Ruby Quiz

    [QUIZ] Secret Santas (#2)

    Ruby Quiz, Oct 1, 2004, in forum: Ruby
    Replies:
    54
    Views:
    465
    Thomas Leitner
    Oct 5, 2004
  3. Peter McMaster

    [SOLUTION] Secret Santas (#2)

    Peter McMaster, Oct 6, 2004, in forum: Ruby
    Replies:
    0
    Views:
    79
    Peter McMaster
    Oct 6, 2004
  4. Peter McMaster

    [SOLUTION] Secret Santas (#2)

    Peter McMaster, Oct 6, 2004, in forum: Ruby
    Replies:
    0
    Views:
    113
    Peter McMaster
    Oct 6, 2004
  5. Ruby Quiz

    [SUMMARY] Secret Santas (#2)

    Ruby Quiz, Oct 7, 2004, in forum: Ruby
    Replies:
    0
    Views:
    127
    Ruby Quiz
    Oct 7, 2004
Loading...

Share This Page