question about iterator

Discussion in 'Ruby' started by Paul Private, Dec 1, 2007.

  1. Paul Private

    Paul Private Guest

    dear
    with the below mentioned script I would like to produce first all of the
    Java courses and then the Ruby ones.
    however I can't seem to get it to work
    I know I can use the partition method but I'm not able to get it to
    work.
    can you please help me out here



    require "collecties/cursus"
    class Cursus_applic
    cursussen = [Cursus.new('Ruby - 1','Jan', 18.15, 10),
    Cursus.new('Ruby - 2','Piet', 18.15, 8),
    Cursus.new('Java - 1','Els', 14, 15),
    Cursus.new('Java - 2','Jan', 14, 10),
    Cursus.new('Java - 3','Piet', 18.15, 8)
    ]

    puts '5. First all Java courses then followed by the others: '
    cursus_java = cursussen.partition {|cursus|cursus_java?(true)}
    puts '6. Alle cursussen gesorteerd op cursus naam: '
    puts '7. Alle cursussen voorafgegaan met de index: '

    end
    and the cursus.rb is mentioned here below
    class Cursus
    attr :naam, false
    attr_reader :docent
    attr :tijdstip, false
    attr_reader :aantal_cursisten
    def initialize naam, docent, tijdstip, aantal
    @naam = naam
    @docent = docent
    @tijdstip = tijdstip
    @aantal_cursisten = aantal
    end

    def overdag?
    @tijdstip < 18
    end

    def naam? cursus_naam
    start = @naam.slice(0, cursus_naam.length)
    start == cursus_naam
    end

    def to_s
    tijdstip = overdag? ? "overdag" : "\'s avonds"
    "\tDe cursus \'#{@naam}\' wordt #{tijdstip} gegeven door #{@docent}"
    end
    end


    thanks for your help
    --
    Posted via http://www.ruby-forum.com/.
     
    Paul Private, Dec 1, 2007
    #1
    1. Advertising

  2. Hi --

    On Sat, 1 Dec 2007, Paul Private wrote:

    > dear
    > with the below mentioned script I would like to produce first all of the
    > Java courses and then the Ruby ones.
    > however I can't seem to get it to work
    > I know I can use the partition method but I'm not able to get it to
    > work.
    > can you please help me out here
    >
    >
    >
    > require "collecties/cursus"
    > class Cursus_applic
    > cursussen = [Cursus.new('Ruby - 1','Jan', 18.15, 10),
    > Cursus.new('Ruby - 2','Piet', 18.15, 8),
    > Cursus.new('Java - 1','Els', 14, 15),
    > Cursus.new('Java - 2','Jan', 14, 10),
    > Cursus.new('Java - 3','Piet', 18.15, 8)
    > ]
    >
    > puts '5. First all Java courses then followed by the others: '
    > cursus_java = cursussen.partition {|cursus|cursus_java?(true)}


    You're using a non-existent method, "cursus_java?" You probably want
    to do:

    java, non_java = cursussen.partition {|cursus| cursus.naam?("Java") }

    or something along those lines.

    > puts '6. Alle cursussen gesorteerd op cursus naam: '
    > puts '7. Alle cursussen voorafgegaan met de index: '
    >
    > end
    > and the cursus.rb is mentioned here below
    > class Cursus
    > attr :naam, false
    > attr_reader :docent
    > attr :tijdstip, false
    > attr_reader :aantal_cursisten


    I believe that attr + false is the same as attr_reader -- except more
    cryptic :) It's best to stick to:

    attr_reader
    attr_writer
    attr_accessor

    since the true/false parameter is not self-explanatory.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details and 2008 announcements!
     
    David A. Black, Dec 1, 2007
    #2
    1. Advertising

  3. Paul Private

    Paul Private Guest

    david thanks for your help
    I have another question here perhaps you can help me out here
    normally when you do a sort it's working like this

    cursus =["java", "cobalt","php","ruby"]
    x=cursus.sort
    puts x

    this is working like a charm but when I try to implement this in the
    code mentioned earlier I get a error message like this
    oefeningen/_cursus_applic.rb:20:in `sort': undefined method `<=>' for
    #<Cursus:0x28b55f4> (NoMethodError)
    from oefeningen/_cursus_applic.rb:20

    how can I solve this one?
    thanks for your help

    Paul
    David A. Black wrote:
    > Hi --
    >
    > On Sat, 1 Dec 2007, Paul Private wrote:
    >
    >> require "collecties/cursus"
    >> class Cursus_applic
    >> cursussen = [Cursus.new('Ruby - 1','Jan', 18.15, 10),
    >> Cursus.new('Ruby - 2','Piet', 18.15, 8),
    >> Cursus.new('Java - 1','Els', 14, 15),
    >> Cursus.new('Java - 2','Jan', 14, 10),
    >> Cursus.new('Java - 3','Piet', 18.15, 8)
    >> ]
    >>
    >> puts '5. First all Java courses then followed by the others: '
    >> cursus_java = cursussen.partition {|cursus|cursus_java?(true)}

    >
    > You're using a non-existent method, "cursus_java?" You probably want
    > to do:
    >
    > java, non_java = cursussen.partition {|cursus| cursus.naam?("Java") }
    >
    > or something along those lines.
    >
    >> puts '6. Alle cursussen gesorteerd op cursus naam: '
    >> puts '7. Alle cursussen voorafgegaan met de index: '
    >>
    >> end
    >> and the cursus.rb is mentioned here below
    >> class Cursus
    >> attr :naam, false
    >> attr_reader :docent
    >> attr :tijdstip, false
    >> attr_reader :aantal_cursisten

    >
    > I believe that attr + false is the same as attr_reader -- except more
    > cryptic :) It's best to stick to:
    >
    > attr_reader
    > attr_writer
    > attr_accessor
    >
    > since the true/false parameter is not self-explanatory.
    >
    >
    > David


    --
    Posted via http://www.ruby-forum.com/.
     
    Paul Private, Dec 1, 2007
    #3
  4. Paul Private

    Todd Benson Guest

    On Dec 1, 2007 10:08 AM, Paul Private <> wrote:
    > david thanks for your help
    > I have another question here perhaps you can help me out here
    > normally when you do a sort it's working like this
    >
    > cursus =["java", "cobalt","php","ruby"]
    > x=cursus.sort
    > puts x
    >
    > this is working like a charm but when I try to implement this in the
    > code mentioned earlier I get a error message like this
    > oefeningen/_cursus_applic.rb:20:in `sort': undefined method `<=>' for
    > #<Cursus:0x28b55f4> (NoMethodError)
    > from oefeningen/_cursus_applic.rb:20
    >
    > how can I solve this one?
    > thanks for your help


    Ruby doesn't know how to compare Cursus objects. You must tell it how
    by defining a <=> method, or you can use the #sort_by method with
    something that understands <=> (like a string).

    If you are simply sorting by alphabetical order of one attribute, then
    here's a simple example...

    class Animal
    attr_reader :name
    def initialize name
    @type = name
    end
    end

    names = %w| tiger bear monkey zebra giraffe |
    zoo = []
    names.each { |n| zoo << Animal.new(n) }

    zoo.each { |a| puts a.name }
    puts "\n------------\n"
    zoo_in_order = zoo.sort_by{ |a| a.name }
    zoo.each { |a| puts a.name }

    Todd
     
    Todd Benson, Dec 1, 2007
    #4
  5. Paul Private

    John Joyce Guest

    On Dec 1, 2007, at 11:58 AM, Todd Benson wrote:

    > On Dec 1, 2007 10:08 AM, Paul Private <> wrote:
    >> david thanks for your help
    >> I have another question here perhaps you can help me out here
    >> normally when you do a sort it's working like this
    >>
    >> cursus =["java", "cobalt","php","ruby"]
    >> x=cursus.sort
    >> puts x
    >>
    >> this is working like a charm but when I try to implement this in the
    >> code mentioned earlier I get a error message like this
    >> oefeningen/_cursus_applic.rb:20:in `sort': undefined method `<=>' for
    >> #<Cursus:0x28b55f4> (NoMethodError)
    >> from oefeningen/_cursus_applic.rb:20
    >>
    >> how can I solve this one?
    >> thanks for your help

    >
    > Ruby doesn't know how to compare Cursus objects. You must tell it how
    > by defining a <=> method, or you can use the #sort_by method with
    > something that understands <=> (like a string).
    >
    > If you are simply sorting by alphabetical order of one attribute, then
    > here's a simple example...
    >
    > class Animal
    > attr_reader :name
    > def initialize name
    > @type = name
    > end
    > end
    >
    > names = %w| tiger bear monkey zebra giraffe |
    > zoo = []
    > names.each { |n| zoo << Animal.new(n) }
    >
    > zoo.each { |a| puts a.name }
    > puts "\n------------\n"
    > zoo_in_order = zoo.sort_by{ |a| a.name }
    > zoo.each { |a| puts a.name }
    >
    > Todd
    >

    Even consider this, simply have class Cursus inherit from another
    class that already implements methods you need such as .sort
    Enumerable or Array might be convenient, but I didn't read all of
    your class Cursus closely...
    In defining your class it is easy to override any inherited method,
    and generally a lot less work to inherit than to create everything
    from nothing.

    Is het voor en hogeschool in het Nederlands? Polytechnische school?
     
    John Joyce, Dec 1, 2007
    #5
  6. Paul Private

    Paul Private Guest

    when I do a sort like this it's working correctly
    class Test
    cursussen = ["ruby","php","c","cobalt","java"]
    z=cursussen.sort { |a, b| a <=> b }
    puts z

    end

    I don't understand why I can't get it to work when I use this
    require "oefeningen/_cursus"
    class Cursus_applic
    cursussen = [Cursus.new("Ruby - 1","Jan", 18.15, 10),
    Cursus.new("Ruby - 2","Piet", 18.15, 8),
    Cursus.new("Java - 1","Els", 14, 15),
    Cursus.new("Java - 2","Jan", 14, 10),
    Cursus.new("Java - 3","Piet", 18.15, 8)
    ]




    puts '5. Alle Java-cursussen, daarna alle andere cursussen: '

    Java, other = cursussen.partition {|cursus| cursus.naam?("Java") }
    puts Java, other

    puts '6. Alle cursussen gesorteerd op cursus naam: '
    z=cursussen.sort { |a, b| a <=> b }
    puts z
    end
    can you or someone help me out
    thanks for your help

    Paul
    John Joyce wrote:
    > On Dec 1, 2007, at 11:58 AM, Todd Benson wrote:
    >
    >>> code mentioned earlier I get a error message like this

    >>
    >> names = %w| tiger bear monkey zebra giraffe |
    >> zoo = []
    >> names.each { |n| zoo << Animal.new(n) }
    >>
    >> zoo.each { |a| puts a.name }
    >> puts "\n------------\n"
    >> zoo_in_order = zoo.sort_by{ |a| a.name }
    >> zoo.each { |a| puts a.name }
    >>
    >> Todd
    >>

    > Even consider this, simply have class Cursus inherit from another
    > class that already implements methods you need such as .sort
    > Enumerable or Array might be convenient, but I didn't read all of
    > your class Cursus closely...
    > In defining your class it is easy to override any inherited method,
    > and generally a lot less work to inherit than to create everything
    > from nothing.
    >
    > Is het voor en hogeschool in het Nederlands? Polytechnische school?


    --
    Posted via http://www.ruby-forum.com/.
     
    Paul Private, Dec 1, 2007
    #6
  7. Hi --

    On Sun, 2 Dec 2007, Paul Private wrote:

    > when I do a sort like this it's working correctly
    > class Test
    > cursussen = ["ruby","php","c","cobalt","java"]
    > z=cursussen.sort { |a, b| a <=> b }
    > puts z
    >
    > end
    >
    > I don't understand why I can't get it to work when I use this
    > require "oefeningen/_cursus"
    > class Cursus_applic
    > cursussen = [Cursus.new("Ruby - 1","Jan", 18.15, 10),
    > Cursus.new("Ruby - 2","Piet", 18.15, 8),
    > Cursus.new("Java - 1","Els", 14, 15),
    > Cursus.new("Java - 2","Jan", 14, 10),
    > Cursus.new("Java - 3","Piet", 18.15, 8)
    > ]
    >
    >
    >
    >
    > puts '5. Alle Java-cursussen, daarna alle andere cursussen: '
    >
    > Java, other = cursussen.partition {|cursus| cursus.naam?("Java") }
    > puts Java, other
    >
    > puts '6. Alle cursussen gesorteerd op cursus naam: '
    > z=cursussen.sort { |a, b| a <=> b }
    > puts z
    > end
    > can you or someone help me out
    > thanks for your help


    When you do:

    a <=> b

    you are actually calling a method on a, with b as argument:

    a.<=>(b)

    If a doesn't have a <=> method, then that's an error. You have to
    define a <=> method for the Cursus class. Typically, that method would
    delegate the comparison to some property of the objects:

    def <=>(other)
    self.name <=> other.name
    end

    or something like that. Then comparing two courses would be
    accomplished by comparing their names.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details and 2008 announcements!
     
    David A. Black, Dec 1, 2007
    #7
  8. Paul Private

    MonkeeSage Guest

    On Dec 1, 2:05 pm, Paul Private <> wrote:
    > when I do a sort like this it's working correctly
    > class Test
    > cursussen = ["ruby","php","c","cobalt","java"]
    > z=cursussen.sort { |a, b| a <=> b }
    > puts z
    >
    > end
    >
    > I don't understand why I can't get it to work when I use this
    > require "oefeningen/_cursus"
    > class Cursus_applic
    > cursussen = [Cursus.new("Ruby - 1","Jan", 18.15, 10),
    > Cursus.new("Ruby - 2","Piet", 18.15, 8),
    > Cursus.new("Java - 1","Els", 14, 15),
    > Cursus.new("Java - 2","Jan", 14, 10),
    > Cursus.new("Java - 3","Piet", 18.15, 8)
    > ]
    >
    > puts '5. Alle Java-cursussen, daarna alle andere cursussen: '
    >
    > Java, other = cursussen.partition {|cursus| cursus.naam?("Java") }
    > puts Java, other
    >
    > puts '6. Alle cursussen gesorteerd op cursus naam: '
    > z=cursussen.sort { |a, b| a <=> b }
    > puts z
    > end
    > can you or someone help me out
    > thanks for your help
    >
    > Paul
    >
    >
    >
    > John Joyce wrote:
    > > On Dec 1, 2007, at 11:58 AM, Todd Benson wrote:

    >
    > >>> code mentioned earlier I get a error message like this

    >
    > >> names = %w| tiger bear monkey zebra giraffe |
    > >> zoo = []
    > >> names.each { |n| zoo << Animal.new(n) }

    >
    > >> zoo.each { |a| puts a.name }
    > >> puts "\n------------\n"
    > >> zoo_in_order = zoo.sort_by{ |a| a.name }
    > >> zoo.each { |a| puts a.name }

    >
    > >> Todd

    >
    > > Even consider this, simply have class Cursus inherit from another
    > > class that already implements methods you need such as .sort
    > > Enumerable or Array might be convenient, but I didn't read all of
    > > your class Cursus closely...
    > > In defining your class it is easy to override any inherited method,
    > > and generally a lot less work to inherit than to create everything
    > > from nothing.

    >
    > > Is het voor en hogeschool in het Nederlands? Polytechnische school?

    >
    > --
    > Posted viahttp://www.ruby-forum.com/.


    Like others have mentioned, you're calling <=> on an instance of class
    Cursus, but haven't defined it for that class. I think what you mean
    is...

    cursussen.sort { |a, b| a.to_s <=> b.to_s }

    ....Cursus#to_s is only implicitly called when a string object is
    required (like for puts, or when it is coerced by "string +", &c).
    Otherwise you have to explicitly call it yourself.

    Regards,
    Jordan
     
    MonkeeSage, Dec 1, 2007
    #8
  9. Paul Private

    Paul Private Guest

    THanks Jordan
    this was exactly what I was looking for

    Paul

    Jordan Callicoat wrote:
    > On Dec 1, 2:05 pm, Paul Private <> wrote:
    >> class Cursus_applic
    >> puts Java, other
    >>
    >> >> zoo.each { |a| puts a.name }
    >> > In defining your class it is easy to override any inherited method,
    >> > and generally a lot less work to inherit than to create everything
    >> > from nothing.

    >>
    >> > Is het voor en hogeschool in het Nederlands? Polytechnische school?

    >>
    >> --
    >> Posted viahttp://www.ruby-forum.com/.

    >
    > Like others have mentioned, you're calling <=> on an instance of class
    > Cursus, but haven't defined it for that class. I think what you mean
    > is...
    >
    > cursussen.sort { |a, b| a.to_s <=> b.to_s }
    >
    > ...Cursus#to_s is only implicitly called when a string object is
    > required (like for puts, or when it is coerced by "string +", &c).
    > Otherwise you have to explicitly call it yourself.
    >
    > Regards,
    > Jordan


    --
    Posted via http://www.ruby-forum.com/.
     
    Paul Private, Dec 2, 2007
    #9
  10. Hi --

    On Sun, 2 Dec 2007, John Joyce wrote:

    >
    > On Dec 1, 2007, at 11:58 AM, Todd Benson wrote:
    >
    >> On Dec 1, 2007 10:08 AM, Paul Private <> wrote:
    >>> david thanks for your help
    >>> I have another question here perhaps you can help me out here
    >>> normally when you do a sort it's working like this
    >>>
    >>> cursus =["java", "cobalt","php","ruby"]
    >>> x=cursus.sort
    >>> puts x
    >>>
    >>> this is working like a charm but when I try to implement this in the
    >>> code mentioned earlier I get a error message like this
    >>> oefeningen/_cursus_applic.rb:20:in `sort': undefined method `<=>' for
    >>> #<Cursus:0x28b55f4> (NoMethodError)
    >>> from oefeningen/_cursus_applic.rb:20
    >>>
    >>> how can I solve this one?
    >>> thanks for your help

    >>
    >> Ruby doesn't know how to compare Cursus objects. You must tell it how
    >> by defining a <=> method, or you can use the #sort_by method with
    >> something that understands <=> (like a string).
    >>
    >> If you are simply sorting by alphabetical order of one attribute, then
    >> here's a simple example...
    >>
    >> class Animal
    >> attr_reader :name
    >> def initialize name
    >> @type = name
    >> end
    >> end
    >>
    >> names = %w| tiger bear monkey zebra giraffe |
    >> zoo = []
    >> names.each { |n| zoo << Animal.new(n) }
    >>
    >> zoo.each { |a| puts a.name }
    >> puts "\n------------\n"
    >> zoo_in_order = zoo.sort_by{ |a| a.name }
    >> zoo.each { |a| puts a.name }
    >>
    >> Todd
    >>

    > Even consider this, simply have class Cursus inherit from another class that
    > already implements methods you need such as .sort
    > Enumerable or Array might be convenient, but I didn't read all of your class
    > Cursus closely...
    > In defining your class it is easy to override any inherited method, and
    > generally a lot less work to inherit than to create everything from nothing.


    The problem, though, is that you don't need Cursus objects to know
    about sort; you need them to know about <=>. The object that needs to
    know about sort is the collection you're sorting, which is (in all
    likelihood) already an array. The objects inside the collection need
    to have the <=> method.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details and 2008 announcements!
     
    David A. Black, Dec 2, 2007
    #10
  11. Paul Private

    MonkeeSage Guest

    On Dec 2, 12:20 am, Paul Private <> wrote:
    > THanks Jordan
    > this was exactly what I was looking for
    >
    > Paul


    Hi Paul,

    Glad to help. One more thing: it would probably look nicer to hide
    that behind <=>

    class Cursus
    ...
    def <=>(other)
    self.to_s <=> other.to_s
    end
    end

    ....then you can call cursussen.sort w/o the block.

    Regards,
    Jordan
     
    MonkeeSage, Dec 2, 2007
    #11
  12. 2007/12/2, MonkeeSage <>:
    > On Dec 2, 12:20 am, Paul Private <> wrote:
    > > THanks Jordan
    > > this was exactly what I was looking for
    > >
    > > Paul

    >
    > Hi Paul,
    >
    > Glad to help. One more thing: it would probably look nicer to hide
    > that behind <=>
    >
    > class Cursus
    > ...
    > def <=>(other)
    > self.to_s <=> other.to_s
    > end
    > end
    >
    > ...then you can call cursussen.sort w/o the block.


    Just a few picky remarks. :) Sorting on the string representation,
    while it may work, is unstable. It's better to sort based on members
    because with your approach you create a dependency between to_s and
    sorting which is neither necessary nor obvious.

    Also, I would only implement this in the class if it is the /default/
    order for instances of Cursus.

    Kind regards

    robert

    --
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Dec 3, 2007
    #12
  13. Paul Private

    MonkeeSage Guest

    On Dec 3, 1:57 am, Robert Klemme <> wrote:
    > 2007/12/2, MonkeeSage <>:
    >
    >
    >
    > > On Dec 2, 12:20 am, Paul Private <> wrote:
    > > > THanks Jordan
    > > > this was exactly what I was looking for

    >
    > > > Paul

    >
    > > Hi Paul,

    >
    > > Glad to help. One more thing: it would probably look nicer to hide
    > > that behind <=>

    >
    > > class Cursus
    > > ...
    > > def <=>(other)
    > > self.to_s <=> other.to_s
    > > end
    > > end

    >
    > > ...then you can call cursussen.sort w/o the block.

    >
    > Just a few picky remarks. :) Sorting on the string representation,
    > while it may work, is unstable. It's better to sort based on members
    > because with your approach you create a dependency between to_s and
    > sorting which is neither necessary nor obvious.
    >
    > Also, I would only implement this in the class if it is the /default/
    > order for instances of Cursus.
    >
    > Kind regards
    >
    > robert
    >
    > --
    > use.inject do |as, often| as.you_can - without end


    I agree with you. In fact, I would have probably implemented the
    courses (Cursus) as ostructs or hashes in the backend. But given to
    current implementation, sorting on to_s amounts sorting on @naam,
    which is, I think, what the OP was asking for. So, while it is
    unstable, generally speaking; here, it amounts to a stable sort on a
    (default) instance variable.

    Regards,
    Jordan
     
    MonkeeSage, Dec 3, 2007
    #13
  14. Robert Klemme wrote:
    > Just a few picky remarks. :) Sorting on the string representation,
    > while it may work, is unstable. It's better to sort based on members
    > because with your approach you create a dependency between to_s and
    > sorting which is neither necessary nor obvious.
    >
    > Also, I would only implement this in the class if it is the /default/
    > order for instances of Cursus.


    And how about performance on using to_s when sorting? Each time an
    object is compared for the sort, 2 string conversions has to be done and
    put in the GC, etc? Has anyone made benchmarks on this?


    Best regards,

    Jari Williamsson
     
    Jari Williamsson, Dec 3, 2007
    #14
    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. Hendrik Maryns
    Replies:
    18
    Views:
    1,429
  2. greg
    Replies:
    6
    Views:
    460
    Dietmar Kuehl
    Jul 17, 2003
  3. Replies:
    6
    Views:
    653
    Jim Langston
    Oct 30, 2005
  4. Steven D'Aprano

    What makes an iterator an iterator?

    Steven D'Aprano, Apr 18, 2007, in forum: Python
    Replies:
    28
    Views:
    1,172
    Steven D'Aprano
    Apr 20, 2007
  5. David Bilsby
    Replies:
    5
    Views:
    2,052
    David Bilsby
    Oct 9, 2007
Loading...

Share This Page