Peculiar Behavior for a Newby to Undertstand

I created a class for prime numbers as so:

class Primes
    def initialize
    end
    
    def prime?(number)
        # Method returns true if number is prime.
        limit = Math.sqrt(number).ceil
        flag = true
        if number % 2 == 0
            flag = false
        else
            3.step(limit,2) {|i|
                if number % i == 0
                    flag = false
                    break
                end
            }
        end
        return flag
    end
    
    def show_primes(lower, upper)
        # Prints all primes between lower and upper
        # Lower is incremented 1 if it is even.
        # The arcane "(((lower/2).floor)*2+1)" performs this task
        (((lower/2).floor)*2+1).step(upper,2) {|i|
            if prime?(i) == true
                print i.to_s + " "
            end
        }
    end
    end
Then when I enter
a=primes.new
a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.
If I enter the same methods outside of class Primes and enter
show_primes(1000000,1000100) I don't get the lower limit at the end of
the printed values.

I am running version 1.18.4 using scite in Ubuntu.

···

--
Charles Gray -- Phoenix, AZ; Where you can bake the chill out of your
bones

Hi Charles,

I entered the code in Ruby 1.8.5 in Windows, using Scintilla IDE :-))
(the joke is that Scintilla-Scite is not an IDE at all!) it gave the error:

ruby prime.rb

prime.rb:34: undefined local variable or method `primes' for main:Object
(NameError)

Then changed

a=primes.new
a.show_primes(1000000,1000100)

to

a=Primes::new
a.show_primes(1000000,1000100)

The good result appeared :slight_smile:

ruby prime.rb

1000003 1000033 1000037 1000039 1000081 1000099 >Exit code: 0

Don't know how you had not an error instead of the wrong result before...
For that you need a Ruby guru :slight_smile:

Kind Regards

J. Augusto

···

On 12/27/06, Charles A Gray <smgspices@aol.com> wrote:

I created a class for prime numbers as so:

class Primes
    def initialize
    end

    def prime?(number)
        # Method returns true if number is prime.
        limit = Math.sqrt(number).ceil
        flag = true
        if number % 2 == 0
            flag = false
        else
            3.step(limit,2) {|i|
                if number % i == 0
                    flag = false
                    break
                end
            }
        end
        return flag
    end

    def show_primes(lower, upper)
        # Prints all primes between lower and upper
        # Lower is incremented 1 if it is even.
        # The arcane "(((lower/2).floor)*2+1)" performs this task
        (((lower/2).floor)*2+1).step(upper,2) {|i|
            if prime?(i) == true
                print i.to_s + " "
            end
        }
    end
Then when I enter
a=primes.new
a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.
If I enter the same methods outside of class Primes and enter
show_primes(1000000,1000100) I don't get the lower limit at the end of
the printed values.

I am running version 1.18.4 using scite in Ubuntu.
--
Charles Gray -- Phoenix, AZ; Where you can bake the chill out of your
bones

Hi --

Then when I enter
a=primes.new

(As another respondent pointed out, you need Primes.new.)

a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.
If I enter the same methods outside of class Primes and enter
show_primes(1000000,1000100) I don't get the lower limit at the end of
the printed values.

I am running version 1.18.4 using scite in Ubuntu.

I can't duplicate the problem, I'm afraid.

David

···

On Wed, 27 Dec 2006, Charles A Gray wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

I created a class for prime numbers as so:

class Primes
    def initialize
    end

    def prime?(number)
        # Method returns true if number is prime.
        limit = Math.sqrt(number).ceil
        flag = true
        if number % 2 == 0
            flag = false
        else
            3.step(limit,2) {|i|
                if number % i == 0
                    flag = false
                    break
                end
            }
        end
        return flag
    end

    def show_primes(lower, upper)
        # Prints all primes between lower and upper
        # Lower is incremented 1 if it is even.
        # The arcane "(((lower/2).floor)*2+1)" performs this task
        (((lower/2).floor)*2+1).step(upper,2) {|i|
            if prime?(i) == true
                print i.to_s + " "
            end
        }
    end
Then when I enter
a=primes.new
a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.
If I enter the same methods outside of class Primes and enter
show_primes(1000000,1000100) I don't get the lower limit at the end of
the printed values.

I am running version 1.18.4 using scite in Ubuntu.
--
Charles Gray -- Phoenix, AZ; Where you can bake the chill out of your
bones

The value of the #step method is the initial value so that is being returned from a.show_primes and presumably printed by whatever you're using to interpret your statements (like irb):

With your code in a file names "primes.rb"

$ irb -rprimes
>> a=Primes.new
=> #<Primes:0x6e5d88>
>> a.show_primes(1_000_000, 1_000_100)
1000003 1000033 1000037 1000039 1000081 1000099 => 1000001
>> a.show_primes(1_000_000, 1_000_100); nil
1000003 1000033 1000037 1000039 1000081 1000099 => nil
>> a.show_primes(1_000_000, 1_000_100); puts ""
1000003 1000033 1000037 1000039 1000081 1000099
=> nil

Note that the value of the last expression is displayed by irb itself. (In the last example, the puts supplies a newline and the value of puts as an expression is nil.)

To see the documentation for the step method (after first trying Fixnum#step and Integer#step rather than looking it up in the pickaxe :wink:

$ ri -T Numeric#step
----------------------------------------------------------- Numeric#step
      num.step(limit, step ) {|i| block } => num

···

On Dec 26, 2006, at 8:20 PM, Charles A Gray wrote:
------------------------------------------------------------------------
      Invokes _block_ with the sequence of numbers starting at _num_,
      incremented by _step_ on each call. The loop finishes when the
      value to be passed to the block is greater than _limit_ (if _step_
      is positive) or less than _limit_ (if _step_ is negative). If all
      the arguments are integers, the loop operates using an integer
      counter. If any of the arguments are floating point numbers, all
      are converted to floats, and the loop is executed _floor(n +
      n*epsilon)+ 1_ times, where _n = (limit - num)/step_. Otherwise,
      the loop starts at _num_, uses either the +<+ or +>+ operator to
      compare the counter against _limit_, and increments itself using
      the +++ operator.

         1.step(10, 2) { |i| print i, " " }
         Math::E.step(Math::PI, 0.2) { |f| print f, " " }

      _produces:_

         1 3 5 7 9
         2.71828182845905 2.91828182845905 3.11828182845905

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

Charles,

I was prepared to be disheartened when I saw that David had responded ahead of me, but I have a solution!

$ irb -f --noprompt -rprimes
a=Primes.new
#<Primes:0x1d5084>
a.show_primes(1_000_000, 1_000_100)
1000003 1000033 1000037 1000039 1000081 1000099 1000001
exit

Since your commands didn't show the typical prompts from irb, I went poking around and came up with this. The '-f' suppresses the ~/.irbrc (which I have), --noprompt ought to be obvious, and -rprimes requires the primes.rb file with your original Primes class definition.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Dec 26, 2006, at 10:07 PM, dblack@wobblini.net wrote:

Hi --

On Wed, 27 Dec 2006, Charles A Gray wrote:

Then when I enter
a=primes.new

(As another respondent pointed out, you need Primes.new.)

a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.
If I enter the same methods outside of class Primes and enter
show_primes(1000000,1000100) I don't get the lower limit at the end of
the printed values.

I am running version 1.18.4 using scite in Ubuntu.

I can't duplicate the problem, I'm afraid.

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
   (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

That was a typo. I actually had a=Primes.new. Which Ruby are you
running?

···

On Wed, 2006-12-27 at 12:07 +0900, dblack@wobblini.net wrote:

> Then when I enter
> a=primes.new

(As another respondent pointed out, you need Primes.new.)

> I created a class for prime numbers as so:
>
> class Primes
> def initialize
> end
>
> def prime?(number)
> # Method returns true if number is prime.
> limit = Math.sqrt(number).ceil
> flag = true
> if number % 2 == 0
> flag = false
> else
> 3.step(limit,2) {|i|
> if number % i == 0
> flag = false
> break
> end
> }
> end
> return flag
> end
>
> def show_primes(lower, upper)
> # Prints all primes between lower and upper
> # Lower is incremented 1 if it is even.
> # The arcane "(((lower/2).floor)*2+1)" performs this task
> (((lower/2).floor)*2+1).step(upper,2) {|i|
> if prime?(i) == true
> print i.to_s + " "
> end
> }
> end
> end
> Then when I enter
> a=primes.new
> a.show_primes(1000000,1000100) I get
> 1000003 1000033 1000037 1000039 1000081 1000099 1000001
> Where is that trailing 1000001 coming from? It is not a prime
> number and
> in fact is the lower limit.
> If I enter the same methods outside of class Primes and enter
> show_primes(1000000,1000100) I don't get the lower limit at the end
of
> the printed values.
>
> I am running version 1.18.4 using scite in Ubuntu.
> --
> Charles Gray -- Phoenix, AZ; Where you can bake the chill out of
your
> bones

The value of the #step method is the initial value so that is being
returned from a.show_primes and presumably printed by whatever
you're
using to interpret your statements (like irb):

With your code in a file names "primes.rb"

$ irb -rprimes
>> a=Primes.new
=> #<Primes:0x6e5d88>
>> a.show_primes(1_000_000, 1_000_100)
1000003 1000033 1000037 1000039 1000081 1000099 => 1000001
>> a.show_primes(1_000_000, 1_000_100); nil
1000003 1000033 1000037 1000039 1000081 1000099 => nil
>> a.show_primes(1_000_000, 1_000_100); puts ""
1000003 1000033 1000037 1000039 1000081 1000099
=> nil

Note that the value of the last expression is displayed by irb
itself. (In the last example, the puts supplies a newline and the
value of puts as an expression is nil.)

To see the documentation for the step method (after first trying
Fixnum#step and Integer#step rather than looking it up in the
pickaxe :wink:

$ ri -T Numeric#step
-----------------------------------------------------------
Numeric#step
      num.step(limit, step ) {|i| block } => num
------------------------------------------------------------------------
      Invokes _block_ with the sequence of numbers starting at _num_,
      incremented by _step_ on each call. The loop finishes when the
      value to be passed to the block is greater than _limit_ (if
_step_
      is positive) or less than _limit_ (if _step_ is negative). If
all
      the arguments are integers, the loop operates using an integer
      counter. If any of the arguments are floating point numbers, all
      are converted to floats, and the loop is executed _floor(n +
      n*epsilon)+ 1_ times, where _n = (limit - num)/step_. Otherwise,
      the loop starts at _num_, uses either the +<+ or +>+ operator to
      compare the counter against _limit_, and increments itself using
      the +++ operator.

         1.step(10, 2) { |i| print i, " " }
         Math::E.step(Math::PI, 0.2) { |f| print f, " " }

      _produces:_

         1 3 5 7 9
         2.71828182845905 2.91828182845905 3.11828182845905

-Rob

Rob, I went back and added the puts for a blank line and got the same
results as before, namely:

a=Primes.new
p a.prime?(1000001)
p a.show_primes(1000000,1000100);puts ""

produced:

ruby primes.rb

false
1000003 1000033 1000037 1000039 1000081 1000099 1000001

Exit code: 0

I am still running it in scite. As well as being a Ruby newby, I am a
Linux newby and haven't figured out how to run irb in Linux.

I am going to reboot into windows and see what happens there.

···

On Wed, 2006-12-27 at 12:23 +0900, Rob Biedenharn wrote:

On Dec 26, 2006, at 8:20 PM, Charles A Gray wrote:

--
Charles Gray -- Phoenix, AZ; Where you can bake the chill out of your
bones

Rob Biedenharn wrote:

The value of the #step method is the initial value so that is being
returned from a.show_primes and presumably printed by whatever you're
using to interpret your statements (like irb):

As a simple example:

  irb(main):001:0> puts 1.step( 2 ){ print "a " }
  a a 1
  => nil

In the above, the block is called twice, and prints out 'a ' each time.
Then the return value of the step method (the initial value) it passed
to the puts function, which prints it out.

You're seeing your first non-even value as the return, since the step
method is the last call in your show_primes method.

One other comment - the pairing of methods you have inside your class
seems odd, given Ruby's built-in classes for numbers. Instead of your
class wrapper, I might personally place those methods as:

  class Integer
    def is_prime?
      # ...
    end
  end

  def show_primes( lower, upper )
  end

Although, since I'm personally not a big fan of 'global' functions, I
might even do:

  class Integer
    def self.show_primes( lower, upper )
      # ...
    end
  end

Tahnks for the reply a=Primes.new ans a=Primes::new both give me the
same incorret result

···

On Wed, 2006-12-27 at 11:51 +0900, Jose Augusto wrote:

a=Primes::new
a.show_primes(1000000,1000100)

The good result appeared :slight_smile:

>ruby prime.rb
1000003 1000033 1000037 1000039 1000081 1000099 >Exit code: 0

Don't know how you had not an error instead of the wrong result
before...
For that you need a Ruby guru :slight_smile:

Kind Regards

J. Augusto

--
Charles Gray -- Phoenix, AZ; Where you can bake the chill out of your
bones

(Sorry, previous message got eaten for some reason. I'll try again.)

Then when I enter
a=primes.new
a.show_primes(1000000,1000100) I get
1000003 1000033 1000037 1000039 1000081 1000099 1000001
Where is that trailing 1000001 coming from? It is not a prime number and
in fact is the lower limit.

If I do exactly the same in my Ruby 1.8.5 irb, I get:

irb(main):034:0> a.show_primes(1000000,1000100)
1000003 1000033 1000037 1000039 1000081 1000099 => 1000001

The 1000001 is the return value of the method, which irb prints after your method finishes printing the primes. So your method does the right thing, but irb output is confusing you.

Just for fun, I've rewritten your code to be shorter and a bit more Rubyish:

class Integer
   def prime?
     return false if self % 2 == 0
     3.step(Math.sqrt(self).ceil, 2) {|i| return false if self % i == 0 }
     true
   end
end

Now you can simply ask n.prime? for any integer n.

Listing primes then becomes as simple as:

(1000000...1000100).select {|i| i.prime? }
=> [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]}

Cheers,

Pete Yandell

···

On 27/12/2006, at 12:20 PM, Charles A Gray wrote:

Opening a terminal and typing irb should just work assuming ruby is installed in a standard fashion. Where to find the terminal will vary a bit by distro. Worst case, you should be able to hit Ctrl+Alt+F1 and jump to a text terminal on any distro (should be Ctrl+Alt+F7 to get you back to X windows, possibly F11). Have fun!
-Mat

···

On Dec 26, 2006, at 11:09 PM, Charles A Gray wrote:

I am still running it in scite. As well as being a Ruby newby, I am a
Linux newby and haven't figured out how to run irb in Linux.

Charles A Gray wrote:

For that you need a Ruby guru :slight_smile:

Kind Regards

J. Augusto

Tahnks for the reply a=Primes.new ans a=Primes::new both give me the
same incorret result

Try this:

class Primes
  def prime?( number )
    ( ( ( number / 2 ).floor ) * 2 + 1 )
  end
end

a = Primes.new
a.prime?( 1000000 )

The last variable assigned is being returned from a.prime? (in this case
an anonymous variable). This is how Ruby returns a value from a method.

Hope this helps.

Joe

···

On Wed, 2006-12-27 at 11:51 +0900, Jose Augusto wrote:

--
Posted via http://www.ruby-forum.com/\.

Charles A Gray escreveu:
[snipped]

I am still running it in scite. As well as being a Ruby newby, I am a
Linux newby and haven't figured out how to run irb in Linux.

I am going to reboot into windows and see what happens there.

That's easy.

Open a shell, and in it, call irb:

$irb

···

On Wed, 2006-12-27 at 12:23 +0900, Rob Biedenharn wrote:

--
Cesar Rabak
GNU/Linux User 52247.
Get counted: http://counter.li.org/