f



"or" and "and"

Hi,

I'm just getting to discover ruby, but I find it very nice programming
language. I just still don't understand how the "or" and "and" in
ruby...

I was playing with ruby and for example made a def to print Stem and
Leaf plot (for those who didn't have a statistics course or slept on
it, e.g. http://cnx.org/content/m10157/latest/)

Here is the Beta version of it:

class Array

def n ; self.size ; end

def stem_and_leaf(st = 1)
	# if st != (2 or 5 or 10) then ; st = 1 ; end
	k = Hash.new(0)
	self.each {|x| k[x.to_f] += 1 }
	k = k.sort{|a, b| a[0].to_f <=> b[0].to_f }
	te_last = 999999999999999999999999999999999 # impossible number
	puts " Stem and Leaf plot" + "     N = " + self.n.to_s + "
Steps / " + st.to_s
	st = 10 / st
	k.each do |key, val|
		te = (key / 10).to_i
		on = (Math.sqrt((key - te * 10).to_i**2)).to_i
		if te == te_last and on < st
			val.times { print on.to_s }
			te_last = te
		elsif te == te_last and on > st and on < st + st
			val.times { print on.to_s }
			te_last = te
			st += st
		else
			print "\n" + "%+6s" % te.to_s + " : "
			val.times { print on.to_s }
			te_last = te
		end
	end
end

end


It prints:

 Stem and Leaf plot     N = 15     Steps / 2

     1 : 234
     1 : 56789
     2 : 019       # it shouldn't be like this
     3 : 08        # it shouldn't be like this
     4 : 07        # it shouldn't be like this

Or with different "steps" value:

 Stem and Leaf plot     N = 15     Steps / 5

     1 : 23
     1 : 4567
     1 : 89
     2 : 019    # it shouldn't be like this
     3 : 08     # it shouldn't be like this
     4 : 07     # it shouldn't be like this

(data:  12 13 14 15 16 17 18 19 20 21 29 30 38 40 47)

My questions:

/1 If I just wanted it to work with "st" values: 1, 2, 5, how should
the "or" statement look like? Ruby don't understand multiple or's (I
tried using different brackets is several places but it still doesn't
work).

/2 It feels like Ruby didn't understand 3 and's in the elsif part of
script. It don't understand the 3rd "and". Why? How to write those
"and" statements?

Thanks in advance : )

If anyone'd like to use the script feel free, I'd be just grateful to
if you cite this message as a source ; )

Greetz,
Timo
0
esuomikim (7)
7/28/2008 10:37:32 AM
comp.lang.ruby 48886 articles. 0 followers. Post Follow

9 Replies
1930 Views

Similar Articles

[PageSpeed] 5

As far as i know ruby deals with multiple ors and ands perfectly well. 
It may be a precedence mixup though:  "or" has lower precedence than 
"||", and similarly, "and" has lower precedence than "&&".  'and' and 
'or' actually have the SAME precedence, which has even more potential 
for error, i think.  Using the symbols, && has higher precedence than 
||.

Try it with the symbol versions, ie || and &&, and see if it's still 
broken, maybe?

Also, i've found that bracketing up multiple logical tests helps a lot: 
the optional omission of the brackets seems to lead to interpreter to do 
something different to what you'd expect, sometimes.

So, instead of this

elsif te == te_last and on > st and on < st + st


try this:

elsif (te == te_last) && (on > st) && (on < (st + st))
-- 
Posted via http://www.ruby-forum.com/.

0
7/28/2008 11:01:01 AM
On 28 Jul 2008, at 11:39, es_ wrote:

> class Array
>
> def n ; self.size ; end
>
> def stem_and_leaf(st = 1)
> 	# if st != (2 or 5 or 10) then ; st = 1 ; end


This won't fly (as you've noticed). you'll need to do either

if st != 2 or st != 5 or st != 10 then st = 1 end

or more consisely

if not [2,5,10].include? st then st = 1 end

or even

[2,5,10].include? st or st = 1

Alex Gutteridge

Department of Biochemistry
University of Cambridge





0
alexg156 (10)
7/28/2008 11:04:25 AM
Note to self - read question properly before answering :)
-- 
Posted via http://www.ruby-forum.com/.

0
7/28/2008 11:11:08 AM
Thanks for help!

The problem is that 3 or's don't work:

?> st = 1
=> 1
>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
=> 1
>>
?> st = 2
=> 2
>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
=> 1
>>
?> st = 2
=> 2
>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
=> 1
>> st = 5
=> 5
>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
=> 1
>> st = 10
=> 10
>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
=> 1

Or with extra brackets:

>> if (st != 2) or (st != 5) or (st != 10) then ; st = 1 ; end
=> 1

Hopefully the "include' option works fine and is beautiful, that's a
great example of simplicity of Ruby I'm getting to appreciate.


And about the brackets, Max Williams wrote, it doesn't work either. I
tried if before. I also know the difference on "and" and "&&", I
revived some articles on that while looking for some info.


Greetz,
Timo
0
esuomikim (7)
7/28/2008 12:42:43 PM
Hi --

On Mon, 28 Jul 2008, es_ wrote:

> Thanks for help!
>
> The problem is that 3 or's don't work:
>
> ?> st = 1
> => 1
>>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
> => 1
>>>
> ?> st = 2
> => 2
>>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
> => 1
>>>
> ?> st = 2
> => 2
>>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
> => 1
>>> st = 5
> => 5
>>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
> => 1
>>> st = 10
> => 10
>>>      if st != 2 or st !=  5 or st !=  10 then ; st = 1 ; end
> => 1

It looks OK to me. What isn't working here?


David

-- 
Rails training from David A. Black and Ruby Power and Light:
  *  Advancing With Rails    August 18-21    Edison, NJ
  * Co-taught by D.A. Black and Erik Kastner
See http://www.rubypal.com for details and updates!

0
dblack (1323)
7/28/2008 12:50:12 PM
> It looks OK to me. What isn't working here?

It checks if st is 2, 5 or 10. I set st to 5 and it says, "wrong"
while it should say "correct".

Greetz,
Timo
0
esuomikim (7)
7/28/2008 12:59:08 PM
es_ wrote:
> It checks if st is 2, 5 or 10. I set st to 5 and it says, "wrong"
> while it should say "correct".

No, it checks whether st is not 2, st is not 5 or st is not 10.
When st is 5 it is still not 10 and not 2. So two out of three conditions are 
true. And with or it suffices if one of the conditions is true.

HTH,
Sebastian
-- 
Jabber: sepp2k@jabber.org
ICQ: 205544826

0
sepp2k (592)
7/28/2008 1:04:47 PM
Hi,

I've spotted the err in and's by printing the st values:

 Stem and Leaf plot     N = 15     Steps / 5
(st =2)
     1 : 2(st =2)3(st =4)
     1 : 4(st =4)5(st =8)6(st =8)7(st =8)
     1 : 8(st =8)9(st =16)
     2 : 0(st =16)1(st =16)9(st =16)
     3 : 0(st =16)8(st =16)
     4 : 0(st =16)7

....stupid mistake, I forgot that it sums it into infinity.

In the "or" example it was just my logical mistake. I mistaken "or"
with "neither"...

Greetz and thanks for help!
Timo
0
esuomikim (7)
7/28/2008 1:35:07 PM
[Note:  parts of this message were removed to make it a legal post.]

On Mon, Jul 28, 2008 at 7:04 AM, Alex Gutteridge <alexg@ruggedtextile.com>wrote:

> On 28 Jul 2008, at 11:39, es_ wrote:
>
>  class Array
>>
>> def n ; self.size ; end
>>
>> def stem_and_leaf(st = 1)
>>        # if st != (2 or 5 or 10) then ; st = 1 ; end
>>
>
>
> This won't fly (as you've noticed).


And as for WHY it doesn't fly.

The expression

  2 or 5 or 10

evaluates to

  2

 since anything but nil or false is 'truthy' in ruby and or returns its left
hand operand it it's truthy otherwise it returns the evaluation of its right
hand operand.

So

   if st !=(2 or 5 or 10) then; st = 1;end

might as well be

  if st != 2 then; st = 1;end


-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

0
rick.denatale (1691)
7/28/2008 11:01:30 PM
Reply: