Ruby idiom for python's for/else while/else

Hi!

Is there a similar construct to python's:

for n in range(2, 10):

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

thx
Gergo

···

--
+-[ Gergely Kontra <kgergely@mcl.hu> http://www.mcl.hu/~kgergely ]------+

PhD Student (Room:IB113) PGP ID: 0x66875624 Mobile:(+36 20)356 9656 |
Budapest University of Technology and Economics ICQ# 175564914 |

+------------- "Olyan langesz vagyok, hogy poroltoval kellene jarnom!" -+

Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):

Is there a similar construct to python's:

>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...

I don't think there's a direct idiom. I'd write this in Ruby as:

(2...10).each do |n|
  fac = (2...n).find { |x| n % x == 0 }
  if fac
    puts "#{n} equals #{fac} * #{n / fac}"
  else
    puts "#{n} is a prime number"
  end
end

This is much clearer IMO.

···

--
William <wmorgan-ruby-talk@masanjin.net>

Hi!

Is there a similar construct to python's:

for n in range(2, 10):

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

Directly, yes; though hardly anybody writes code this way (at least I've never seen anybody write something like this, like how I'm about to give it to you). I'd see William Morgan's message for a better suggestion.

for n in (2..10) do
   for x in (2..n) do
     if n % x == 0
       puts "#{n} equals #{x} * #{n/x}"
       break
     else
       puts "#{n} is a prime number"
     end
   end
end

···

On 19-Sep-05, at 7:15 PM, Gergely Kontra wrote:

Gergo

--
Jeremy Tregunna
jtregunna@blurgle.ca

"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra

i would probably use catch/throw:

   harp:~ > cat a.rb
   (2 ... 10).each do |n|
     x = catch('x'){(2 ... n).each{|x| throw 'x', x if n % x == 0}; nil}
     if x
       puts "#{ n } = #{ n } * #{ x }/#{ n }"
     else
       puts "#{ n } is prime"
     end
   end

   harp:~ > ruby a.rb
   2 is prime
   3 is prime
   4 = 4 * 2/4
   5 is prime
   6 = 6 * 2/6
   7 is prime
   8 = 8 * 2/8
   9 = 9 * 3/9

cheers.

-a

···

On Tue, 20 Sep 2005, Gergely Kontra wrote:

Hi!

Is there a similar construct to python's:

for n in range(2, 10):

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

Here's another:

(2...10).each do |n|
  unless (2...n).any? do |x|
           if n % x == 0
             puts "#{n} equals #{x} * #{n/x}"
             true
           end #else nil
         end
    puts "#{n} is a prime number"
  end
end

But, really, I'd rather write it like William Morgan did.

Devin

Gergely Kontra wrote:

···

Hi!

Is there a similar construct to python's:

for n in range(2, 10):
       

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
... 2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

thx
Gergo

Gergely Kontra <kgergely <at> mcl.hu> writes:

Hi!

Is there a similar construct to python's:

>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

Almost identical, but not necessarily the Ruby way:

  for n in 2 ... 10
    for x in 2 ... n
      if n % x == 0
        puts "#{n} equals #{x} * #{n/x}"
        break
      end
    end and puts "#{n} is a prime number"
  end

Regards,
Pit

Meh, I think the Python version is much clearer. Each to his own, I guess.

···

On 9/19/05, William Morgan <wmorgan-ruby-talk@masanjin.net> wrote:

Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):
> Is there a similar construct to python's:
>
> >>> for n in range(2, 10):
> ... for x in range(2, n):
> ... if n % x == 0:
> ... print n, 'equals', x, '*', n/x
> ... break
> ... else:
> ... # loop fell through without finding a factor
> ... print n, 'is a prime number'
> ...

I don't think there's a direct idiom. I'd write this in Ruby as:

(2...10).each do |n|
  fac = (2...n).find { |x| n % x == 0 }
  if fac
    puts "#{n} equals #{fac} * #{n / fac}"
  else
    puts "#{n} is a prime number"
  end
end

This is much clearer IMO.

Hi --

Hi!

Is there a similar construct to python's:

for n in range(2, 10):

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

Directly, yes; though hardly anybody writes code this way (at least I've never seen anybody write something like this, like how I'm about to give it to you). I'd see William Morgan's message for a better suggestion.

for n in (2..10) do
for x in (2..n) do

You'd want the ... range operator, so as to exclude the upper limit.

   if n % x == 0
     puts "#{n} equals #{x} * #{n/x}"
     break
   else
     puts "#{n} is a prime number"
   end
end
end

Have you run it? :slight_smile: It doesn't work the same way; it prints
"...prime number" for *every* time a match isn't found, until a match
is found. So, for example, you get:

7 is a prime number # printed 5 times (2,3,4,5,6)
8 equals 2 * 4
9 is a prime number
9 equals 3 * 3

David

···

On Tue, 20 Sep 2005, Jeremy Tregunna wrote:

On 19-Sep-05, at 7:15 PM, Gergely Kontra wrote:

--
David A. Black
dblack@wobblini.net

William Morgan wrote:

Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):

Is there a similar construct to python's:

for n in range(2, 10):
         

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
   
I don't think there's a direct idiom. I'd write this in Ruby as:

(2...10).each do |n|
fac = (2...n).find { |x| n % x == 0 }
if fac
   puts "#{n} equals #{fac} * #{n / fac}"
else
   puts "#{n} is a prime number"
end
end

This is much clearer IMO.

Yeah, this isn't any clearer, but here's one that demonstrates the possibilities in tying iterators and conditionals together. It works because `break' causes the iterator to return nil.

  for n in 2...10
    puts "#{ n } is a prime number" if
      for x in 2...n
        if n % x == 0
          puts "#{ n } equals #{ x }*#{ n/x }"
          break
        end
      end
  end

_why

> Hi!
>
> Is there a similar construct to python's:
>
>>>> for n in range(2, 10):
> ... for x in range(2, n):
> ... if n % x == 0:
> ... print n, 'equals', x, '*', n/x
> ... break
> ... else:
> ... # loop fell through without finding a factor
> ... print n, 'is a prime number'
> ...
> 2 is a prime number
> 3 is a prime number
> 4 equals 2 * 2
> 5 is a prime number
> 6 equals 2 * 3
> 7 is a prime number
> 8 equals 2 * 4
> 9 equals 3 * 3

Directly, yes; though hardly anybody writes code this way (at least
I've never seen anybody write something like this, like how I'm about
to give it to you). I'd see William Morgan's message for a better
suggestion.

# I hate for loops

2.upto(10) do |n| # was => for n in (2..10) do
    2.upto(n) do |x| # was => for x in (2..n) do

     if n % x == 0
       puts "#{n} equals #{x} * #{n/x}"
       break
     else
       puts "#{n} is a prime number"
     end
   end
end

Though, I think this is broken... check the output.

> Gergo

--
Jeremy Tregunna
jtregunna@blurgle.ca

"If debugging is the process of removing bugs, then programming must be
the process of putting them in." --Dykstra

I still think lists are the nicest way to go about this. It could be
much improved but this is shorter:
(2..10).select {|n| (2..n).select {|x| n % x == 0 and n != x }.empty? }

Brian,

···

On 9/19/05, Jeremy Tregunna <jtregunna@blurgle.ca> wrote:

On 19-Sep-05, at 7:15 PM, Gergely Kontra wrote:

Hi --

William Morgan wrote:

Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):

Is there a similar construct to python's:

for n in range(2, 10):

... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...

I don't think there's a direct idiom. I'd write this in Ruby as:

(2...10).each do |n|
fac = (2...n).find { |x| n % x == 0 }
if fac
   puts "#{n} equals #{fac} * #{n / fac}"
else
   puts "#{n} is a prime number"
end
end

This is much clearer IMO.

Yeah, this isn't any clearer, but here's one that demonstrates the possibilities in tying iterators and conditionals together. It works because `break' causes the iterator to return nil.

for n in 2...10
  puts "#{ n } is a prime number" if
    for x in 2...n
      if n % x == 0
        puts "#{ n } equals #{ x }*#{ n/x }"
        break
      end
    end
end

I know I'm wandering into the golf realm, rather than the clarity
realm, but just for fun:

   for n in 2...10
     puts "#{ n } is a prime number" if
       for x in 2...n
         break puts("#{ n } equals #{ x }*#{ n/x }") if n % x == 0
       end
   end

David

···

On Tue, 20 Sep 2005, why the lucky stiff wrote:

--
David A. Black
dblack@wobblini.net

This is annoying - builtin loops and "loop" returns nil whereas
many of the object method loops (for..in is just the each
method) return the object. Using a builtin loop, you can do
something like this to get something much closer to python's
while/else (becomes while/or in ruby):

(2...10).each do |n|
  x = 2
  while x<n
    if n % x == 0
      puts "#{ n } equals #{ x }*#{ n/x }"
      break(x)
    end
    x += 1
  end or
  puts "#{ n } is a prime number"
end

I think that's the closest your going to get to python's
while/else. You have the use the opposite polarity for the for
loop as why demonstrated. One of my RCR's is about this
inconsistency. I think all of the loop methods should return
nil by default (with break(ret) causing it to return something
else).

···

--- why the lucky stiff <ruby-talk@whytheluckystiff.net> wrote:

William Morgan wrote:

>Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):
>
>
>>Is there a similar construct to python's:
>>
>>
>>
>>>>>for n in range(2, 10):
>>>>>
>>>>>
>>... for x in range(2, n):
>>... if n % x == 0:
>>... print n, 'equals', x, '*', n/x
>>... break
>>... else:
>>... # loop fell through without finding a factor
>>... print n, 'is a prime number'
>>...
>>
>>
>
>I don't think there's a direct idiom. I'd write this in Ruby
as:
>
>(2...10).each do |n|
> fac = (2...n).find { |x| n % x == 0 }
> if fac
> puts "#{n} equals #{fac} * #{n / fac}"
> else
> puts "#{n} is a prime number"
> end
>end
>
>This is much clearer IMO.
>
Yeah, this isn't any clearer, but here's one that
demonstrates the
possibilities in tying iterators and conditionals together.
It works
because `break' causes the iterator to return nil.

  for n in 2...10
    puts "#{ n } is a prime number" if
      for x in 2...n
        if n % x == 0
          puts "#{ n } equals #{ x }*#{ n/x }"
          break
        end
      end
  end

_why

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005

Brian Mitchell wrote:

···

On 9/19/05, Jeremy Tregunna <jtregunna@blurgle.ca> wrote:
>
> On 19-Sep-05, at 7:15 PM, Gergely Kontra wrote:
>
> > Hi!
> >
> > Is there a similar construct to python's:
> >
> >>>> for n in range(2, 10):
> > ... for x in range(2, n):
> > ... if n % x == 0:
> > ... print n, 'equals', x, '*', n/x
> > ... break
> > ... else:
> > ... # loop fell through without finding a factor
> > ... print n, 'is a prime number'
> > ...
> > 2 is a prime number
> > 3 is a prime number
> > 4 equals 2 * 2
> > 5 is a prime number
> > 6 equals 2 * 3
> > 7 is a prime number
> > 8 equals 2 * 4
> > 9 equals 3 * 3
>
> Directly, yes; though hardly anybody writes code this way (at least
> I've never seen anybody write something like this, like how I'm about
> to give it to you). I'd see William Morgan's message for a better
> suggestion.
>

# I hate for loops

2.upto(10) do |n| # was => for n in (2..10) do
    2.upto(n) do |x| # was => for x in (2..n) do
> if n % x == 0
> puts "#{n} equals #{x} * #{n/x}"
> break
> else
> puts "#{n} is a prime number"
> end
> end
> end
>

Though, I think this is broken... check the output.

> > Gergo
>
> --
> Jeremy Tregunna
> jtregunna@blurgle.ca
>
> "If debugging is the process of removing bugs, then programming must be
> the process of putting them in." --Dykstra
>

I still think lists are the nicest way to go about this. It could be
much improved but this is shorter:
(2..10).select {|n| (2..n).select {|x| n % x == 0 and n != x }.empty? }

Brian,

(2...50).select{|n|(2..Math.sqrt(n).to_i).select{|x|n % x == 0}.empty?}
     -->
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

I agree that the Python construct is clearer...
*if* you're familiar with the for...else construct.

There are occasions where this construct is very useful,
but it seems to be a slight contradiction to Python's motto of
"There should be one -- and preferably only one -- obvious way
to do it."

Tim Hammerquist

···

Joe Van Dyk <joevandyk@gmail.com> wrote:

William Morgan <wmorgan-ruby-talk@masanjin.net> wrote:
> Excerpts from Gergely Kontra's mail of 19 Sep 2005 (CDT):
> > >>> for n in range(2, 10):
> > ... for x in range(2, n):
> > ... if n % x == 0:
> > ... print n, 'equals', x, '*', n/x
> > ... break
> > ... else:
> > ... # loop fell through without finding a factor
> > ... print n, 'is a prime number'
>
> I don't think there's a direct idiom. I'd write this in Ruby
> as:
>
> (2...10).each do |n|
> fac = (2...n).find { |x| n % x == 0 }
> if fac
> puts "#{n} equals #{fac} * #{n / fac}"
> else
> puts "#{n} is a prime number"
> end
> end
>
> This is much clearer IMO.

Meh, I think the Python version is much clearer. Each to his
own, I guess.

William James schrieb:

...
(2...50).select{|n|(2..Math.sqrt(n).to_i).select{|x|n % x == 0}.empty?}
     -->
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Should be a little bit more efficient:

   (2...50).reject{|n|(2..Math.sqrt(n)).find{|x|n % x == 0}}

It's not what the OP wanted, though.

Regards,
Pit

Agree.

Michel.

···

On 9/19/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:

I think that's the closest your going to get to python's
while/else. You have the use the opposite polarity for the for
loop as why demonstrated. One of my RCR's is about this
inconsistency. I think all of the loop methods should return
nil by default (with break(ret) causing it to return something
else).

Yeah. I just thought I would post it. Mostly equivalent to what he was
doing but quite different in what tools were used. Yours is much more
elegant either way.

If I was serious about the prime numbers I would have built a
quadratic sieve of some sort. I also hate for-loops (in most cases).
:wink:

Brian.

···

On 9/20/05, Pit Capitain <pit@capitain.de> wrote:

William James schrieb:
> ...
> (2...50).select{|n|(2..Math.sqrt(n).to_i).select{|x|n % x == 0}.empty?}
> -->
> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Should be a little bit more efficient:

   (2...50).reject{|n|(2..Math.sqrt(n)).find{|x|n % x == 0}}

It's not what the OP wanted, though.

Regards,
Pit

Pit Capitain wrote:

  (2...50).reject{|n|(2..Math.sqrt(n)).find{|x|n % x == 0}}

It's not what the OP wanted, though.

include Math
primes = (2...10).map{|n|(2..sqrt(n)).find{|x|n % x == 0}}
primes.each_with_index do |x,n|
  n += 2
  if x then puts "#{n} equals #{x} * #{n/x}"
  else puts "#{n} is a prime number" end
end
__END__

It is now.

Or, for readability's sake:

include Math
primes = (2...10).map{|n|[n,(2..sqrt(n)).find{|x|n % x == 0}]}
primes.each do |n,x|
  if x then puts "#{n} equals #{x} * #{n/x}"
  else puts "#{n} is a prime number" end
end
__END__

So, no, there may not be an exact equivalent to for/else, but as with interface definitions in Python/Ruby, you generally find that the need isn't there like it is in the other language. In Java, types are staticly declared, and mixins are nonexistent, making interfaces very important. In Python, there's a difference between statements and expressions (IIUC), making special iterator constructs like for/else important. IOW, it shouldn't be considered a fault of Ruby's that it doesn't include that construct -- it doesn't need it.

Devin