From: sempsteen Date: 2006-11-25T22:37:55+09:00 Subject: Re: coding practise correction: this also does two method calls puts hsh['id'] if hsh['id'] != nil this is the one which i wanted to write, only one method call: result = hsh['id'] puts result if result != nil On 11/25/06, sempsteen wrote: > Thanks for your replies Gareth and Paul. > I've improved return statement as you suggested Paul. > this didn't worked: > return self == t2 and self != t1 > but this: > return (self == t2 and self != t1) > and this: > self == t2 and self != t1 > worked. > > I've also set the sums' initial values to 1 and start the loops from 2 > which is more reasonable. > Paul, i understood your code. > Amicable numbers was just an example. I actually want to know where to > use the method pairs like: > has_key? [], > has_friend?, friend > has_sth?, give_that > ... > > When we call "has_friend?" method it does the same job as "friend" > method except that it returns true or false not the amicable number. > When we call "Hash#has_key?" method it does the same job as "Hash#[]" > method except that it returns true or false, not the value of the > given Hash index. > > So if they both do the same job why do i need to search for an > existing value and then call another method that gives the value like: > hsh = {'id' => 10, 'lang' => 'Ruby'} > puts hsh['id'] if hsh.has_key?('id') > > I can write it like this: > puts hsh['id'] if hsh['id'] != nil > > I hope i could explain it. > > On 11/25/06, Paul Lutus wrote: > > sempsteen wrote: > > > > > Hi all, > > > First of all sorry for my english. > > > I'm a Ruby newbie, trying to learn the language from the book, "The > > > Pragmatic Programmer's Guide". I loved the language very much. Now i > > > have some question marks about some issues. > > > If you help me understand this concept i'll be very happy. > > > > > > 1-) What does "Hash#has_key?" actually do? > > > > It returns true if provided with a key that is present in the hash. > > > > > Why do we need such a method in spite of using the result of "Hash#[]" > > > method which will return nil for a non-present key. > > > > The method has_key? is faster than using the key to find and return a value, > > which is what Hash#[] must do. > > > > > 2-) If we go ahead by the same manner is this a correct way of writing > > > a program that finds amicable numbers: > > > > > > class Fixnum > > > def has_friend? > > > t1, t2 = 0, 0 > > > 1.upto(self / 2) {|i| t1 += i if self % i == 0} > > > 1.upto(t1 / 2) {|i| t2 += i if t1 % i == 0} > > > > For this section: > > > > > if self == t2 and self != t1 > > > return true > > > else > > > return false > > > > Use this: > > > > return self == t2 and self != t1 > > > > This produces the same result. > > > > Also, in each of your loops you are testing whether a particular number can > > be divided by one with no remainder. The answer is always yes, so for each > > calculated value skip this test (start with 2 not 1) and set the initial > > value equal to 1. > > > > An article about amicable numbers, with some facts that may improve your > > method of calculating them: > > > > http://en.wikipedia.org/wiki/Amicable_number > > > > About the general topic, it is more efficient to compile an array of divisor > > sums and compare in that fashion than to test each number separately as you > > are doing. Like this: > > > > ----------------------------------------------- > > > > #!/usr/bin/ruby -w > > > > hash = {} > > > > max = 10000 > > > > 2.upto(max) do |i| > > sum = 1 > > 2.upto(i/2) do |j| > > sum += j if (i % j) == 0 > > end > > hash[i] = sum > > end > > > > hash.keys.sort.each do |i| > > a = hash[i] > > b = hash[a] > > puts "#{a} <-> #{b}" if a != b && b == i > > end > > > > ----------------------------------------------- > > > > Output: > > > > 284 <-> 220 > > 220 <-> 284 > > 1210 <-> 1184 > > 1184 <-> 1210 > > 2924 <-> 2620 > > 2620 <-> 2924 > > 5564 <-> 5020 > > 5020 <-> 5564 > > 6368 <-> 6232 > > 6232 <-> 6368 > > > > -- > > Paul Lutus > > http://www.arachnoid.com > > > > > >