question about iterator

P

Paul Private

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
 
D

David A. Black

Hi --

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
 
P

Paul Private

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 said:
Hi --

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
 
T

Todd Benson

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
 
J

John Joyce

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

Paul Private

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 said:
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?
 
D

David A. Black

Hi --

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
 
M

MonkeeSage

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

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
 
D

David A. Black

Hi --

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
 
M

MonkeeSage

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
 
R

Robert Klemme

2007/12/2 said:
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
 
M

MonkeeSage

2007/12/2, MonkeeSage <[email protected]>:








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

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
 
J

Jari Williamsson

Robert said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top